【问题标题】:random function in C++C++中的随机函数
【发布时间】:2012-08-24 07:54:17
【问题描述】:

有没有在指定范围内生成k个随机数的函数。 例如,我想要 5 个介于 0 到 100 之间的随机数,有或没有替换。

【问题讨论】:

  • 没有内置函数,但是写起来比较简单。查看动态创建数组和 rand 函数。编辑:我看第一个答案是正确的。
  • @drescherjm - 你可以调用它 5 次。它每次都会生成一个新的随机数。如果您不了解您的代码无法正常工作的原因,您需要为我们提供更多帮助。
  • @Ramhound。对不起。当我看到解决有或没有更换部件的提升答案时,我删除了我的评论。

标签: c++ function random


【解决方案1】:

是的,C++ 中有一个 rand() 函数,可以在程序中使用它,包括 cstdlib 头文件。 您可以使用以下代码来实现您的程序。

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
  int max {100};
  int min {0};
  int number;
  int count = 5; //assuming that only 10 numbers we need to print
  srand(time(0));
  for(int i=1;i<=count;i++)
  {
      number = rand() % (max - min +1) + min;``
      cout<<number<<endl;
  }
}

【讨论】:

【解决方案2】:

例如,您可以使用 Boost 库来生成随机数。 以下代码从 [0, 100] 替换生成 5 个随机数:

#include <vector>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>

const int numWantedNumbers = 5;

int main()
{
    boost::random::mt19937 generator;
    boost::random::uniform_int_distribution<> distribution(0, 100);
    std::vector<int> result;
    for (int i = 0; i < numWantedNumbers; ++i)
        result.push_back(distribution(generator));
}

如果您想生成不替换的数字,只需检查它们是否是 仍然可用:

#include <algorithm>
#include <vector>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>

const int numWantedNumbers = 5;

int main()
{
    boost::random::mt19937 generator;
    boost::random::uniform_int_distribution<> distribution(0, 100);
    std::vector<int> result;
    while (result.size() < numWantedNumbers)
    {
        int number = distribution(generator);
        if (std::find(result.begin(), result.end(), number) == result.end())
            result.push_back(number);
    }
}

注意:示例中的无放回拒绝采样有一个明显的缺点,即较长的向量很难创建。试着画出 99 100 个数字,看看我的意思(或者更好地从 10000 中抽取 9999)。如果这 是一个问题,我建议创建所有可能数字的随机排列 然后按照要求的大小切割向量:

#include <algorithm>
#include <vector>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>

const int numWantedNumbers = 5;

int main()
{
    boost::random::mt19937 generator;
    boost::random::uniform_int_distribution<> distribution(0, 100);

    // Generate a vector with all possible numbers and shuffle it.
    std::vector<int> result;
    for (int i = 0; i <= 100; ++i)
        result.push_back(i);
    for (int i = 0; i <= 100; ++i)
    {
        int x = distribution(generator);
        std::swap(result[i], result[x]);
    }

    // Truncate to the requested size.
    result.resize(numWantedNumbers);
}

根据juanchopanza的建议进行编辑

在 C++11 方式中,最后一个变体看起来像这样

#include <algorithm>
#include <random>
#include <vector>

const int numWantedNumbers = 5;

int main()
{
    std::random_device device;
    std::mt19937 generator(device());
    std::uniform_int_distribution<> distribution(0, 100);

    // Generate a vector with all possible numbers and shuffle it.
    std::vector<int> result;
    for (int i = 0; i <= 100; ++i)
        result.push_back(i);
    std::random_shuffle(result.begin(), result.end());

    // Truncate to the requested size.
    result.resize(numWantedNumbers);
}

g++-4.6 可以愉快地编译它,如果你添加了-std=c++0x 开关。

编辑:使用std::random_shuffle()(坦克到James Kanze)。

【讨论】:

  • 第二个算法可能会非常慢,如果需要的数字数量接近范围。 (有时)更好的解决方案是用可能的值填充std::vector,在其上调用std::random_shuffle,然后获取第一个n。如果所需的数字数量远小于范围,则此解决方案可能需要大量额外内存。
  • 您可能想补充一点,其中大部分在 C++11 中也可用,请参阅 here
  • @JamesKanze:我添加了一个不使用拒绝抽样的变体。
  • @juanchopanza:谢谢,也添加了 C++11 版本。
  • @Mehrwolf 做了很多不必要的工作。并且无论如何可能不会给出随机分布。将第二个循环替换为对 std::random_shuffle 的调用。
【解决方案3】:

您可以将std::generate_nrand() 或来自新C++11 random number generators 的生成器一起使用。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2014-04-27
  • 2014-08-19
  • 2016-07-17
  • 2014-01-16
  • 2013-06-27
  • 2011-06-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多