はい、いいえ、「唯一の方法」の意味によって異なります。はい、終了が保証されている方法がないため、できる最善の方法は(と一般的な値に対して)確率1で終了するアルゴリズムです。いいえ、「無駄」を小さくすることができます好きなように。NR
一般的に保証された終了が不可能な理由
決定論的な計算エンジン(チューリングマシンまたはボートに浮かぶもの)に加えて、要素セットランダムな要素を生成する神託があるとします。あなたの目標は、要素セット要素を生成することです。エンジンの出力は、oracleによって返される値のシーケンスのみに依存します。これは、潜在的に無限のシーケンス関数です。R[0..R−1]N[0,N−1]f(r0,r1,r2,…)
エンジンが最大で回Oracleを呼び出すとします。オラクルが回未満呼び出されるトレースがある場合があります。その場合、常に正確に回呼び出されるようにoracleを余分に呼び出しても、出力は変更されません。したがって、一般性を失うことなく、オラクルは正確に回呼び出されると仮定します。その場合、結果確率は、とようなシーケンスです。オラクルは一様なランダムジェネレーターであるため、各シーケンスは等確率であり、確率はです。したがって、各結果の確率は、形式ですmm m x (r 0、… 、r m − 1)f (r 0、… 、r m − 1)= x 1 / R m A / R m A 0 R mmmmx(r0,…,rm−1)f(r0,…,rm−1)=x1/RmA/Rmここで、の間の整数であり、及び。A0Rm
場合分割いくつかのために、その後、上に均一な分布を生成することができランダム発生器を呼び出すことによって素子倍(これは読者の課題として残されています)。それ以外の場合、これは不可能です。確率結果を取得する方法はありません。この条件は、のすべての素因数も因数であると言うことに等しいことに注意してください(これは、質問で書いたものよりも許容範囲が広いです;たとえば、6面のフェアで4つの中からランダムな要素を選択できます4は6を分割しませんが、死にます。R m m N m 1 / N N RNRmmNm1/NNR
無駄を減らす
戦略では、場合、すぐに再描画する必要はありません。直観的に、はエントロピーが少し残っておりこれをミックスに保持できます。[ kr≥kN[kN..R−1]
しばらくの間、実際に未満の乱数を永久に生成し続け、ドローを作成して一度に乱数を生成すると仮定します。このグループ化された世代で単純な棄却サンプリングを行う場合、描画の無駄は、つまり剰余をドローの数で割ったもの。これはと同じくらい小さい場合があります。ときと互いに素、あなたは十分に大きな値を選択することにより、廃棄物を任意に小さくすることができます。および一般的な値の場合u d d R d − kNudd RdmodNugcd(R、N)Rd−kNudRdmodNugcd(R,N)RNdRN、と別々に考慮する必要があるため、計算はより複雑になりますが、十分に大きいグループで無駄を小さくすることができます。gcd(R,N)N/gcd(R,N)
実際には、比較的効率の悪い乱数(暗号化など)であっても、が小さい場合を除き、単純な拒否サンプリング以外の価値はほとんどありません。たとえば、が通常2のべき乗で、が通常数百または数千ビットである暗号化では、均一な乱数生成は通常、所望の範囲での直接拒否サンプリングによって進行します。NRN