2

指定した範囲内で k 個の乱数を生成する関数はありますか。たとえば、置換の有無にかかわらず、0 から 100 までの 5 つの乱数が必要です。

4

3 に答える 3

6

std::generate_nを、rand()または新しいC++11 乱数ジェネレーターのジェネレーターと共に使用できます。

于 2012-08-29T16:29:10.880 に答える
3

たとえば、乱数を生成するために使用できる 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);
    }
}

注:置換なしの例の拒否サンプリングには、長いベクトルを作成するのが非常に難しいという明らかな欠点があります。私の言いたいことを理解するために、100 の数字から 99 を引いてみてください (または、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

編集: ( James Kanzestd::random_shuffle()へのタンク)を利用してください。

于 2012-08-29T16:37:16.067 に答える