C++ で範囲内の乱数を生成する

胡金庫 2023年10月12日
  1. C++11 <random> ライブラリを使用して範囲内の乱数を生成する
  2. 範囲内の乱数を生成するために rand 関数を使用する
C++ で範囲内の乱数を生成する

この記事では、指定した数値間隔で乱数を生成する方法について、複数の C++ の方法を紹介します。

C++11 <random> ライブラリを使用して範囲内の乱数を生成する

C++ では、C++11 のリリースに伴い、乱数生成のための標準ライブラリ機能が新しいヘッダ <random> の下に追加されました。<random> ヘッダーが提供する RNG ワークフロー機能は、ランダムエンジンと分布の 2つの部分に分かれています。ランダムエンジンは予測不可能なビットストリームを返す役割を担っています。ディストリビューションは、一様分布、正規分布、その他の確率分布を満たす乱数(ユーザが指定した型)を返します。

最初に、ユーザはランダムエンジンをシード値で初期化しなければなりません。非決定論的ランダムビットのシステム固有のソースである std::random_device を用いてエンジンをシードすることが推奨されます。これにより、エンジンは実行ごとに異なるランダムビットストリームを生成することができます。一方、ユーザが複数のプログラムを実行する際に同じシーケンスを生成する必要がある場合、ランダムエンジンは定数 int リテラルで初期化されなければなりません。

次に、乱数が生成される区間の最小/最大値の引数を用いて分布オブジェクトを初期化します。以下の例では、uniform_int_distribution を用いて 10 個の整数を任意にコンソールに出力しています。

#include <iostream>
#include <random>

using std::cout;
using std::endl;

constexpr int MIN = 1;
constexpr int MAX = 100;

constexpr int RAND_NUMS_TO_GENERATE = 10;

int main() {
  std::random_device rd;
  std::default_random_engine eng(rd());
  std::uniform_int_distribution<int> distr(MIN, MAX);

  for (int n = 0; n < RAND_NUMS_TO_GENERATE; ++n) {
    cout << distr(eng) << "; ";
  }
  cout << endl;

  return EXIT_SUCCESS;
}

出力:

57; 38; 8; 69; 5; 27; 65; 65; 73; 4;

<random> ヘッダーは、異なるアルゴリズムと効率性のトレードオフを持つ複数のランダムエンジンを提供します。したがって、次のコードサンプルに示すように、特定のランダムエンジンを初期化することができます。

#include <iostream>
#include <random>

using std::cout;
using std::endl;

constexpr int MIN = 1;
constexpr int MAX = 100;

constexpr int RAND_NUMS_TO_GENERATE = 10;

int main() {
  std::random_device rd;
  std::mt19937 eng(rd());
  std::uniform_int_distribution<int> distr(MIN, MAX);

  for (int n = 0; n < RAND_NUMS_TO_GENERATE; ++n) {
    cout << distr(eng) << "; ";
  }
  cout << endl;

  return EXIT_SUCCESS;
}

出力:

59; 47; 81; 41; 28; 88; 10; 12; 86; 7;

範囲内の乱数を生成するために rand 関数を使用する

rand 関数は C 標準ライブラリの一部であり、C++ のコードから呼び出すことができます。高品質の乱数生成に rand 関数を使用することは推奨されないが、配列や行列を任意のデータで埋めるために利用することができます。この例では、この関数は 0 から MAX の数値間隔の間の乱数を生成します。この関数は、複数回の実行で異なる値を生成するために、std::srand (できれば現在の時刻を std::time(nullptr) で渡す) で種付けしなければならないことに注意してください。

#include <ctime>
#include <iostream>
#include <random>

using std::cout;
using std::endl;

constexpr int MIN = 1;
constexpr int MAX = 100;

constexpr int RAND_NUMS_TO_GENERATE = 10;

int main() {
  std::srand(std::time(nullptr));
  for (int i = 0; i < RAND_NUMS_TO_GENERATE; i++) cout << rand() % MAX << "; ";
  cout << endl;

  return EXIT_SUCCESS;
}

出力:

36; 91; 99; 40; 3; 60; 90; 63; 44; 22;
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C++ Random