公正なコインが与えられ、公正な(6面の)ダイスを繰り返し反転する確率分布をシミュレートしたいとします。私の最初のアイデアは、2 k = 6 mのような適切な整数を選択する必要があるということです。そうコイン投げた後のk回、我々は範囲を分割することにより、ダイの出力にK個の長さのビット列によりコード番号をマッピングする[ 0 、2 のk - 1 ] 6にインターバル長の各M。ただし、2 kには2つの唯一の素因数がありますが、は3が含まれます。これを行う他の簡単な方法があるはずですよね?
公正なコインが与えられ、公正な(6面の)ダイスを繰り返し反転する確率分布をシミュレートしたいとします。私の最初のアイデアは、2 k = 6 mのような適切な整数を選択する必要があるということです。そうコイン投げた後のk回、我々は範囲を分割することにより、ダイの出力にK個の長さのビット列によりコード番号をマッピングする[ 0 、2 のk - 1 ] 6にインターバル長の各M。ただし、2 kには2つの唯一の素因数がありますが、は3が含まれます。これを行う他の簡単な方法があるはずですよね?
回答:
@FrankWが指摘する方法よりもわずかに効率的な方法を使用するために同じアイデアを使用するには、コインを回反転して2 n未満の数を取得します。次に、これをm個のダイフリップのバッチとして解釈します。ここで、mは最大数であるため、6 m < 2 n(既に述べたように、ここでは平等は成り立ちません)。6 m以上の数値を取得した場合、値を拒否して、n回すべてのフリップを繰り返す必要があります。
コインフリップを作成することで単一のダイフリップを返す関数を実装し、次のm − 1個のダイフリップリクエストの結果をキャッシュできます。
興味深い点は、拒否率が低いため、一部の値が他の値よりも優れていることです。良い値のリストは次のとおりです(つまり、前の値よりも拒否率が低い値)。
n m r
3 1 0.25
8 3 0.15625
13 5 0.05078125
44 17 0.0378308072686
75 29 0.0247036782182
106 41 0.0113974522704
243 94 0.00933096248381
380 147 0.00726015308463
517 200 0.00518501504347
654 253 0.00310553931213
791 306 0.00102171682348
式を用いて得られた: 。
最初の行は、拒否率25%の@FrankWの回答に対応しています。次の数値が便利ですとn = 13の両方を単一の整数静的変数に保持できます。特に、n = 13の棄却率はわずか5%であり、これは25%に対して賢明な改善であり、可能な実装の良い候補となります。
できることは、拒絶サンプリングと呼ばれる方法を採用することです:
6以来可能性のある結果のうち 8つが各セットで終了するため、サイコロを得るためにlセット以上のフリップが必要になる確率は(1−6。したがって、この方法は実際には効率的です。
改善点:
@Angel's answer points out, that the number of coin flips in each set but the first can be reduced from 3 to 2, by using the distinction between a and a as the first bit for the next set.
@Emanuele Paolini explains, how you can reduce the number of rerolls, if you need multiple die rolls.
An alternative to rejection sampling (as described in FrankW's answer) is to use a scaling algorithm, that takes into account an answer of [7,8] as if it was another coin flipping.
There is a very detailed explanation at mathforum.org, including the algorithm (its NextBit()
would be flipping your fair coin).
The case for throwing a dice with a fair coin (sampling 2 → 6) is easier than the generic algorithm. You just take a failure (7 or 8) as another coin input and perform two more flips.
Another approach to simulate a roll of a dN using a dM (in the case of the specific question asked a d6 using a d2) is to partition the interval [0, 1) into N equal intervals of length 1/N, [0, 1/N), [1/N, 2/N), ..., [(N-1)/N, N).
Use the dM to generate a base-M fraction, 0.bbbb..., in [0, 1). If that falls in [(i-1)/N, i/N), take i as the roll of the dN. Note that you only have to generate enough base-M digits of the fraction to determine which interval it is in.
I am giving this explanation as it may hopefully help simplify understanding or analysis of probabilities in some situations.
FrankW suggests using rejection sampling, flipping the coin three times, keeping the result if it is in the right range, or repeating the three flips otherwise, until success.
Ángel suggests to save one flip on each trial, replacing it by a the binary choice remaining from the two unused values of the previous set of three.
This means really that one bit of information was produced with the first three flips, that did not need to be produced. More precisely, you should need to flip the coin only twice to know whether the current set of flips will be successful.
Knowing whether the current set of flip will be successful is the only probability that matters, since interpreting a successful set of flip is probability independent. And this can be known before all the flips are completed for that set.
This can be achieved in at least two ways, or more precisely in two different interpretations of the flips. There may be others.
Grouping results in pairs
The idea is to consider only three values (1,2), (3,4) and (5,6) represented by any three double-flip configurations, say TT, TH, HT. Then, you can apply rejection sampling with double-flips, repeating whenever you get the failure configuration HH.
Once you get one of the three successful configurations, you just flip the coin once more to decide whether you should take the first or the second value of the corresponding pair.
Early detection of flip-set failure
The idea is to use a slightly different reading of the three-flip configuration. If Head and Tail are interpreted as 1 and 0, then a configuration should correspond to the binary interpretation plus one. That is TTT (i.e. 000) corresponds 1, HTH (i.e. 101) corresponds 6, HHT (i.e. 110) and HHH (i.e. 111) corresponds to 7 and 8, or anything outside [1,6].
その後、最初の2回のフリップだけでフリップセットが成功または失敗することがわかります。HHが生成される場合、フリップセットは最後のフリップとは無関係に失敗します。したがって、スキップできます。
早期発見だと思うは常に説明として使用できるますが、シミュレートされたサイコロの顔の数によっては、可変回数のフリップの後に障害検出が発生する場合があります。
たとえば、10面のサイコロの場合、原則として、失敗に対応する6つの構成を持つ4つのフリップのフリップセットが必要です。トリックは、次のようにバイナリ値のシーケンスの上位ですべての障害構成を保持することです。
TTTT 0000 1
HTTT 1000 9
HTTH 1001 10
HTHT 1001 11
HTHH 1011 12
HHTT 1100 13
HHHH 1111 16
成功した構成は範囲[1、10]に対応し、失敗は範囲[11、16]に対応します。
その後、最初の2つのフリップがHHを与えるか、最初の3つのフリップがHTHを与えると、セットの欠落しているフリップを試みる必要もなく失敗します。
失敗しない場合は、フリップのセットを終了するだけです。
これには2つのよく知られたアプローチがあります。1つは「拒否サンプリング」です。たとえば、3つのビットを使用して6つの値から1つを選択し、2つの追加サンプルを再試行します。または、14ビット(8192値)を使用して1から6までの5つの値(7776の可能性)を選択し、256ケース中13ケースで再試行します。
もう1つは、圧縮/圧縮解除アルゴリズムの圧縮解除部分を使用することです。算術コーディングを使用すると、1〜6のランダムな値のシーケンスをほとんど冗長性なしに圧縮できます。圧縮されたシーケンスをランダムに生成し、解凍します。これははるかに複雑ですが、実際には追加の乱数は必要ありません。
説明が不要な場合は、事前に申し訳ありません。どのくらい詳細を説明するのか、コンセプトを理解するのがどれほど簡単かはわかりませんでした。
3枚のコイン(フェアコイン)があるとします。各コインの両側に値を増分的に割り当てると、6つの値が得られます。
そのように:最初のコインの頭は1、尾は2です。2番目のコインでは、頭は3、尾は4です。3番目のコインでは、頭は5、尾は6です。
コインを反転すると、現在のセットである3つの数字のセットが残ります。これで、現在のセットが以前のセットになり、プロセスを繰り返して3つの数字の新しいセットを取得します。
現在のセットから以前のセットに一致する番号が1つだけになるまで、これを繰り返します。それがあなたの番号です。
したがって、現在のセットで[heads、tails、heads]を取得した場合、それは[1、4、5]になります。今、あなたは再びそれらをひっくり返して、あなたの現在のセットは[2、4、5]です。2つの一致。ダメ。もう一回やってみよう。[2、3、6]を取得します。一致するのは1つだけです。あなたの番号は2です。
任意の数が表示される可能性は等しくありますが、特定のセットのペアが成功するのは3/32の変更(1つの一致のみ)であるため、特に費用対効果は高くありません。したがって、平均して、アルゴリズムは約10回繰り返す必要があります。また、奇数のダイに簡単に一般化することはできません。
少なくとも、思考の糧かもしれません。非常に興味深い質問です。
コインを3回裏返し、結果を2進数として解釈し、範囲外の結果を拒否します。
たとえば、headsを1にし、tailsを0にします。3回裏返して、heads、tails、headsを取得した場合、バイナリ101(10進数で5)になります。HHT = 110b =6。TTT= 000b = 0およびHHH = 111b =7。これらは両方とも範囲外であり、拒否されます。すべての数字を再度反転します。
残念ながら、公正なコイン(のシーケンス)を使用して(公正な)ダイスを(忠実に)シミュレートすることはできません。
単に、ダイスのイベントスペースの次元が そしてこれは、の力によって正確に一致させることはできません (フェアコインのイベントスペースが提供するものです)。
しかし、公正な「トライコイン」を使用してこれを行うことができます(そのような用語を使用できる場合)。3つの結果を持つコインを意味します。そして、単純な2コインであるため、これら2コインのジョイントスペースは、ダイスのイベントスペースと正確に一致します。
いくつかの回答で述べたように、拒絶サンプリングは実際の近似シミュレーションを提供します。ただし、(有限時間で)ある程度のエラーまたは確率の不一致が残っています。したがって、これら2つのシステムのイベントスペースを実際に一致させたい場合、機能しない場合があります。
(棄却サンプリングがその例である)確率論的シミュレーションでは、生成された典型的なシーケンスは実際に相対的な基本確率(この場合はダイのイベント空間)を実際に示します。ただし、(コメントで述べたように)これらの典型的な各シーケンスには、まったく同じ結果の任意の長いサブシーケンスを含めることができます。つまり、リジェクションサンプリングを使用する場合(場合によって)、イベントスペースの一部の過剰表示または過少表示のために、任意の時間がかかるか、生成された分布に偏りが生じる(つまり、公平ではない)ことを意味します。これが当てはまらない場合は、決定論的アルゴリズムが可能になります。これは、ダイスとコイン(次元では一致しません)のイベントスペースに正確に一致します。