[解決済み] なぜrand()%6に偏りがあるのですか?
疑問点
std::randの使い方を読んでいたら、以下のようなコードが見つかりました。 cppreference.com
int x = 7;
while(x > 6)
x = 1 + std::rand()/((RAND_MAX + 1u)/6); // Note: 1+rand()%6 is biased
右の式は何が問題なのでしょうか?試してみましたが、完全に動作します。
どのように解決するのですか?
には2つの問題があります。
rand() % 6
(この
1+
はどちらの問題にも影響しません)。
まず、いくつかの回答で指摘されているように、もし下位ビットの
rand()
が適切に一様でない場合、余剰演算子の結果もまた一様ではありません。
次に、もし
rand()
が6の倍数でない場合、残りは高い値より低い値を多く生成します。これはたとえ
rand()
が完全に分散した値を返す場合でも同じです。
極端な例として
rand()
が一様な分布の値を生成するとします。
[0..6]
. これらの値に対する余りを見てみると
rand()
が範囲内の値を返した場合
[0..5]
の範囲にある値を返し、余りは
[0..5]
. このとき
rand()
は 6 を返します。
rand() % 6
は0を返します。
rand()
が0を返した場合と同様に0を返します。つまり、他のどの値よりも2倍多くの0を持つ分布が得られます。
2つ目は
リアル
の問題です。
rand() % 6
.
その問題を回避する方法として
を破棄することです。
の値で、一様でない重複を生成することです。以下である6の最大倍数を計算するのです。
RAND_MAX
以下である6の最大倍数を計算し、いつでも
rand()
がその倍数以上の値を返すたびにそれを拒否し、必要な回数だけ再び `rand() を呼び出します。
というわけで。
int max = 6 * ((RAND_MAX + 1u) / 6)
int value = rand();
while (value >= max)
value = rand();
これは問題のコードの別の実装で、何が起こっているかをより明確に示すことを意図しています。
関連
-
[解決済み] 解決済み] `pthread_create' への未定義の参照 [重複] [重複
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] なぜC++はPythonよりもstdinからの行の読み込みが遅いのですか?
-
[解決済み] なぜテンプレートはヘッダーファイルでしか実装できないのですか?
-
[解決済み] ランダムな文字列を使用するこのコードは、なぜ "hello world" と表示されるのですか?
-
[解決済み】画像処理。コカ・コーラ缶」認識のためのアルゴリズム改良
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
-
[解決済み】なぜC++プログラマは'new'の使用を最小限に抑えなければならないのでしょうか?
最新
-
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++でユーザー入力を待つ【重複あり
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み】std::cin.getline( ) vs. std::cin
-
[解決済み】デバッグアサーションに失敗しました
-
[解決済み】Eclipse IDEでC++エラー「nullptrはこのスコープで宣言されていません」が発生する件
-
[解決済み】乱数生成器を使うとモジュロバイアスがかかると言われるのはなぜ?
-
[解決済み] ある範囲から乱数を生成する方法