[解決済み] <random> はLinuxでは同じ数字を生成するが、Windowsでは生成しない。
質問
以下のコードは、区間 [1,100] にある5つの疑似乱数のリストを生成するためのものである。私は
default_random_engine
で
time(0)
で、システム時間を返します。
ユニックス時間
. このプログラムを Windows 7 上で Microsoft Visual Studio 2013 を使ってコンパイルして実行すると、期待通りに動作します (下記参照)。しかし、Arch Linux で g++ コンパイラーを使用してそうすると、奇妙な動作になります。
Linux では、毎回 5 つの数字が生成されます。最後の 4 つの数字は実行ごとに異なりますが (よくあることです)、最初の数字は同じままです。
WindowsとLinuxで5回実行したときの出力例です。
| Windows: | Linux:
---------------------------------------
Run 1 | 54,01,91,73,68 | 25,38,40,42,21
Run 2 | 46,24,16,93,82 | 25,78,66,80,81
Run 3 | 86,36,33,63,05 | 25,17,93,17,40
Run 4 | 75,79,66,23,84 | 25,70,95,01,54
Run 5 | 64,36,32,44,85 | 25,09,22,38,13
さらに謎なのは、その最初の数字が Linux 上で定期的に 1 つずつ増加することです。上記の出力を得た後、私は約 30 分待ち、再度試したところ、最初の数字が変更されており、現在は常に 26 として生成されていることがわかりました。その後も定期的に1ずつ増え続け、現在は32になっています。の値の変化と対応しているようです。
time(0)
.
なぜ最初の数字は実行中にほとんど変化せず、変化したときに1だけ増加するのですか?
コードです。5つの数字とシステム時間をきちんとプリントアウトしています。
#include <iostream>
#include <random>
#include <time.h>
using namespace std;
int main()
{
const int upper_bound = 100;
const int lower_bound = 1;
time_t system_time = time(0);
default_random_engine e(system_time);
uniform_int_distribution<int> u(lower_bound, upper_bound);
cout << '#' << '\t' << "system time" << endl
<< "-------------------" << endl;
for (int counter = 1; counter <= 5; counter++)
{
int secret = u(e);
cout << secret << '\t' << system_time << endl;
}
system("pause");
return 0;
}
どのように解決するのですか?
こんな感じです。
-
default_random_engine
は libstdc++ (GCC の標準ライブラリ) の中でminstd_rand0
であり、これは単純な線形合同エンジンです。typedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647> minstd_rand0;
-
このエンジンが乱数を生成する方法は、x i+1 = (16807x i + 0) mod 2147483647.
-
したがって、種が1だけ異なる場合、ほとんどの場合、最初に生成される数は16807だけ異なることになります。
-
このジェネレータの範囲は[1, 2147483646]です。libstdc++ の方法である
uniform_int_distribution
がこれを範囲 [1, 100] の整数にマップする方法は、本質的に次のとおりです。n
. この数が 2147483600 よりも大きくない場合は、以下を返します。(n - 1) / 21474836 + 1
を返す。そうでなければ、新しい数字で再試行する。大半の場合、2つの
n
が 16807 だけ異なる場合、この手順では [1, 100] で同じ数字が得られることが容易にわかるでしょう。実際、生成された数は約 21474836 / 16807 = 1278 秒または 21.3 分ごとに 1 つ増加すると予想され、これはあなたの観測とよく一致しています。
MSVC の
default_random_engine
は
mt19937
であり、この問題はありません。
関連
-
[解決済み】 unsigned int vs. size_t
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み】C++エラーです。"配列は中括弧で囲まれたイニシャライザーで初期化する必要がある"
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み】C++の余分な資格エラー
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み】VC++の致命的なエラーLNK1168:書き込みのためにfilename.exeを開くことができません。
-
[解決済み】変数やフィールドがvoid宣言されている
-
[解決済み] LinuxでCPU/コアの数をコマンドラインから取得する方法は?
-
[解決済み] WindowsとLinuxのディレクトリ名で禁止されている文字は何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み】C++ 非推奨の文字列定数から「char*」への変換について
-
[解決済み】C-stringを使用すると警告が表示される。"ローカル変数に関連するスタックメモリのアドレスが返される"
-
[解決済み】C++でユーザー入力を待つ【重複あり
-
[解決済み】変数 '' を抽象型 '' と宣言できない。
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】fpermissiveフラグは何をするのですか?
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み] 式はクラス型を持つ必要があります。
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)