公正なコインを与えられたダイをシミュレートする方法


21

公正なコインが与えられ、公正な(6面の)ダイスを繰り返し反転する確率分布をシミュレートしたいとします。私の最初のアイデアは、2 k = 6 mのような適切な整数を選択する必要があるということです。そうコイン投げた後のk回、我々は範囲を分割することにより、ダイの出力にK個の長さのビット列によりコード番号をマッピングする[ 0 2 のk - 1 ] 6にインターバル長の各M。ただし、2 kには2つの唯一の素因数がありますが、k,m2k=6mk[0,2k1]m2kは3が含まれます。これを行う他の簡単な方法があるはずですよね?6m


問題がより一般的な方法で処理されるこの質問を参照してください。
ラファエル

この件に関する記事があります。拒否サンプリングの使用方法と、「浪費された」ビットを再利用してさらにロールを高速化する方法について説明します。
ZeroUltimax

回答:


12

@FrankWが指摘する方法よりもわずかに効率的な方法を使用するために同じアイデアを使用するには、コインを回反転して2 n未満の数を取得します。次に、これをm個のダイフリップのバッチとして解釈します。ここで、mは最大数であるため、6 m < 2 n(既に述べたように、ここでは平等は成り立ちません)。6 m以上の数値を取得した場合、値を拒否して、n回すべてのフリップを繰り返す必要があります。n2nmm6m<2n6mn

コインフリップを作成することで単一のダイフリップを返す関数を実装し、次のm 1個のダイフリップリクエストの結果をキャッシュできます。nm1

興味深い点は、拒否率が低いため、一部の値が他の値よりも優れていることです。良い値のリストは次のとおりです(つまり、前の値よりも拒否率が低い値)。n

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

式を用いて得られた:

m=nlog32r=13m2n

最初の行は、拒否率25%の@FrankWの回答に対応しています。次の数値が便利ですn = 13の両方を単一の整数静的変数に保持できます。特に、n = 13の棄却率はわずか5%であり、これは25%に対して賢明な改善であり、可能な実装の良い候補となります。n=8n=13n=13


6 ^ mは必要ありません。6* mで十分です。したがって、5回のスローを使用して、1/16のケースのみを拒否する5ビットの数値を取得できます。
Taemyr

3回投げた場合の25%と比較すると、13回投げた場合の拒否率は5%です。なぜなら、3回のトスで25%が0.390625%のケースで4回しか拒否しない(つまり、12回以上トスを使う)からです。
Taemyr

@Taemyrの5ビットの数値は32個の異なる値を表すことができ、単一のサイコロを表すことができます(2つのサイコロには36の可能性があるため)。そうのみ6/32値が27/32 = 84%の割合を拒否すると許容される
エマニュエルパオリーニ

@Taemyr:の速度拒否上のn個の平均でのすべてのバッチ、投げ手段N投げは、確率で拒否されますRを。したがって、平均して、各トスは同じレートrnに依存しない)で拒否されます。rnnrrn
エマヌエーレパオリーニ14

はい。3回のトスで25%の再噴射率を持つFrankWの方法を使用すると、4回目までに1〜0.00390625の確率で受け入れられます。
Taemyr

29

できることは、拒絶サンプリングと呼ばれる方法を採用することです:

  • コインを3回フリップし、各フリップをビット(0または1)として解釈します。
  • バイナリ数を与える、3ビットを連結する[0,7]
  • 番号がである場合、ダイスロールとしてそれを取ります。[1,6]
  • それ以外の場合、つまり結果がまたは7の場合、フリップを繰り返します。07

6以来可能性のある結果のうち 8つが各セットで終了するため、サイコロを得るためにlセット以上のフリップが必要になる確率は1668l。したがって、この方法は実際には効率的です。(168)l=14l

改善点:

@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 0 and a 7 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.


Wouldn't this method give greater central tendency that a true d6 would?
Red_Shadow

3
@Red_Shadow No. Note that you don't add the coin tosses (three wouldn't be enough, then) but you pick each bit in a k-bit binary number by coin. Thus, you sample uniformly from [0..2k1] and reject numbers not from the target interval; this can only yield a uniform distribution on the target interval.
Raphael

If you're crafty with the rejected range, it's actually easy in this case to use that to reduce the number of necessary coin flips in the rejection case.
Mooing Duck

@MooingDuck you can decide whether to discard your result after 2 tosses: if it is 0,0 0,1 or 1,0 then toss again for the last bit otherwise start over
ratchet freak

1
@NikosM. The probability to take longer than k steps is decreasing towards zero exponentially, though, so the answer makes no wrong claim: it is efficient in practice, and in fact used widely. (For more complicated distributions, it's often the only known method. At all.)
Raphael

7

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.


2

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.


The termination condition needs to be made more precise. If I flip the coin once I end up with either the binary fraction 0.0 or 0.1 (i.e ½), both of which fall into an interval (corresponding to 0 and 3, respectively, in this case). You need to regard the generated fraction as a range and you stop when the entire range is within a single interval. I'm sure that's what you intended but I don't think it's clear.
rici

1

A possibly simpler explanation of improved rejection sampling.

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を与えると、セットの欠落しているフリップを試みる必要もなく失敗します。

失敗しない場合は、フリップのセットを終了するだけです。


1

これには2つのよく知られたアプローチがあります。1つは「拒否サンプリング」です。たとえば、3つのビットを使用して6つの値から1つを選択し、2つの追加サンプルを再試行します。または、14ビット(8192値)を使用して1から6までの5つの値(7776の可能性)を選択し、256ケース中13ケースで再試行します。

もう1つは、圧縮/圧縮解除アルゴリズムの圧縮解除部分を使用することです。算術コーディングを使用すると、1〜6のランダムな値のシーケンスをほとんど冗長性なしに圧縮できます。圧縮されたシーケンスをランダムに生成し、解凍します。これははるかに複雑ですが、実際には追加の乱数は必要ありません。


0

説明が不要な場合は、事前に申し訳ありません。どのくらい詳細を説明するのか、コンセプトを理解するのがどれほど簡単かはわかりませんでした。

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回繰り返す必要があります。また、奇数のダイに簡単に一般化することはできません。

少なくとも、思考の糧かもしれません。非常に興味深い質問です。


4
これは常に大規模に実行され、拒否サンプリングよりも大幅に悪化します。拒否サンプリングの場合は、反転するだけですログn シミュレートするコイン n-sided dieとフリップの各セットは、厳密に大きい確率で成功します 12。提案している方法では、反転する必要がありますn2 コインとフリップの各セットは確率でのみ成功します n/2n
デビッドリチャービー14

0

コインを3回裏返し、結果を2進数として解釈し、範囲外の結果を拒否します。

たとえば、headsを1にし、tailsを0にします。3回裏返して、heads、tails、headsを取得した場合、バイナリ101(10進数で5)になります。HHT = 110b =6。TTT= 000b = 0およびHHH = 111b =7。これらは両方とも範囲外であり、拒否されます。すべての数字を再度反転します。


1
それはちょうどフランクの答えです。
ラファエル

2
@Raphael実際、フランクは予想される実行時間に対処するため、フランクの答えの厳密なサブセットです。
デビッドリチャービー14

0

残念ながら、公正なコイン(のシーケンス)を使用して(公正な)ダイスを(忠実に)シミュレートすることはできません。

単に、ダイスのイベントスペースの次元が 6 そしてこれは、の力によって正確に一致させることはできません 2 (フェアコインのイベントスペースが提供するものです)。

しかし、公正な「トライコイン」を使用してこれを行うことができます(そのような用語を使用できる場合)。3つの結果を持つコインを意味します。そして、単純な2コインであるため、これら2コインのジョイントスペースは、ダイスのイベントスペースと正確に一致します。

いくつかの回答で述べたように、拒絶サンプリングは実際の近似シミュレーションを提供します。ただし、(有限時間で)ある程度のエラーまたは確率の不一致が残っています。したがって、これら2つのシステムのイベントスペースを実際に一致させたい場合、機能しない場合があります。

(棄却サンプリングがその例である)確率論的シミュレーションでは、生成された典型的なシーケンスは実際に相対的な基本確率(この場合はダイのイベント空間)を実際に示します。ただし、(コメントで述べたように)これらの典型的な各シーケンスには、まったく同じ結果の任意の長いサブシーケンスを含めることができます。つまり、リジェクションサンプリングを使用する場合(場合によって)、イベントスペースの一部の過剰表示または過少表示のために、任意の時間がかかるか、生成された分布に偏りが生じる(つまり、公平ではない)ことを意味します。これが当てはまらない場合は、決定論的アルゴリズムが可能になります。これは、ダイスとコイン(次元では一致しません)のイベントスペースに正確に一致します。


コメントは詳細なディスカッション用ではありません。この会話はチャットに移動さました
ジル「SO-悪であるのをやめる」14

@Gillesは、あまりにも悪い負の投票に行ったすべての説明と(正確さ)チャットにもかかわらず、まだここにある:P
ニコスM.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.