【问题标题】:Can't Generate Full Range of Random for Integers无法为整数生成全范围的随机数
【发布时间】:2013-04-09 17:58:34
【问题描述】:

我正在尝试生成一个包含 0 到 100 000 之间的 10000 个整数的文件,以便稍后对它们进行 MergeSort。

当我使用 fstream 生成文件时,我从来没有得到超过 32760 的整数。

以下方法生成文件,然后将其读回并检查任何超过 32750 的整数。我通常会得到介于 32750 和 32760 之间的 3-5 个整数。为什么会发生这种情况,我该如何解决?是种子问题还是Random函数的实际使用?

// sizeOfArray = 10000
void generateFile() {
    ofstream fout("unsorted.txt");
    srand(time(NULL));

    // Generating the file
    int num;
    for(int i = 0; i < sizeOfArray; i++) {
         num = rand() % 100000;
         if(i < sizeOfArray-1)
            //fout << i+1 << ": " << num << endl;
            fout << num << endl;
         else
            //fout << i+1 << ": " << num;
            fout << num;
    }

    // Reading the File Back
    ifstream fin("unsorted.txt");
    for(int i = 0; i < sizeOfArray; i++) {
        fin >> num;
        if(num > 32750)
            cout << num << endl;
    }

    cin.get();
}

已解决
使用下面提供的答案,我生成了 500 次文件
我收到的最高整数是 99931。

【问题讨论】:

  • 即随机数生成器的范围。使用不同的随机数生成器,或者取两个随机数并将它们组合成一个。
  • 根据cplusplus.com,rand()的范围是0 - RAND_MAXRAND_MAX 依赖于库,但至少应该是 32767
  • 你知道可以给我所需范围的随机数生成器吗?
  • P.S.这实际上是一个很好的问题——在这个时代,随机数的范围应该这么小并不明显。你遇到的限制在 20 年前会更合适。
  • 添加 3 个随机数不会给你一个平等的分布。这与掷两个骰子更有可能得到 7 而非 2 的原因相同。

标签: c++ file-io random ifstream


【解决方案1】:

您可以从rand() 获得的最高随机值是RAND_MAX,这是一个依赖于库的常量。在您的情况下,它似乎设置为 2^15-1,这是适合有符号 16 位整数的最大正数。

当您需要生成大于RAND_MAX 的数字时,请多次调用rand(),每次乘以RAND_MAX。例如,在您的情况下,以下代码应该可以工作(我假设您的 int 有 32 位):

num = rand();
num *= RAND_MAX;
num += rand();
num %= 100000;

请注意,仅将三个随机数相加以获得所需范围不会产生与乘加法相同的随机分布。

【讨论】:

  • 为什么包含行 num += rand() ?我在没有那条线的情况下尝试过,仍然收到非常接近 100 000 的整数。
  • @Gander7:如果你不做num += rand(),你的结果(在修改之前)总是RAND_MAX的倍数。您也可以这样想:如果RAND_MAX 是 2 的幂,则相当于进行左移和 OR 以分别设置位部分。
  • 啊,即使 rand() 已经使用过一次,如果没有那行,我仍然只能得到 32767 个数字。它们将是原始的 32767 * RAND_MAX。第二个 Rand() 是为了使结果多样化。 @jamesdlin 谢谢。
  • @Gander7 想象一个rand(),它返回从 0 到 99 的值。假设您需要一个数字 0..9999。正确的做法是rand()*100+rand():第一个rand()填写前两位数,第二个填写后两位数。你可以只使用rand()*100,但你永远不会得到一个从 0 到 99、从 100 到 199、从 200 到 299 等等的数字。
  • 顺便说一句,我不喜欢使用 % 100000 来获取 [0, 100000) 范围内的随机数,因为它会引入偏差并且因为 c-faq.com/lib/notveryrand.html
【解决方案2】:

您可以使用随 C++11 引入的新随机数生成器之一来获得更大的范围:http://en.cppreference.com/w/cpp/numeric/random

如果你没有 C++11,你也可以从 Boost 获得它:http://www.boost.org/doc/libs/1_53_0/doc/html/boost_random.html

【讨论】:

  • rand() 是一个绝望的案例,切换到其中一个。
【解决方案3】:

取决于你使用的是什么:http://www.cplusplus.com/reference/cstdlib/RAND_MAX/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-20
    • 1970-01-01
    • 1970-01-01
    • 2013-11-19
    • 2014-08-11
    • 2010-12-24
    • 2010-09-22
    相关资源
    最近更新 更多