11


2

バイアスされたものを使用するバイアスされていない乱数ジェネレータ

確率pで1、確率(1-p)で0を生成するバイアス乱数ジェネレーターがあります。 pの値がわかりません。 これを使用して、確率0.5で1、確率0.5で0を生成する不偏乱数ジェネレータを作成します。

:この問題は、Cormen、Leiserson、Rivest、Steinによるアルゴリズムの紹介の演習問題です(clrs)

5 Answer


20


イベント(p)(1-p)と(1-p)(p)は同等の確率です。 それらをそれぞれ0と1として、他の2組の結果を破棄すると、不偏ランダムジェネレーターが得られます。

コードでは、これは次のように簡単に実行できます。

int UnbiasedRandom()
{
    int x, y;

    do
    {
        x = BiasedRandom();
        y = BiasedRandom();
    } while (x == y);

    return x;
}


4


フォンノイマンに起因するトリックは、一度に2ビットを取得するというもので、01は0に対応し、10は1に対応し、00または11を繰り返すことはすでに発生しています。 このメソッドを使用して単一のビットを取得するために抽出する必要があるビットの期待値は「1 / p(1-p)」であり、「p」が特に小さいか大きい場合はかなり大きくなる可能性があるため、尋ねる価値があります特に、多くの情報(すべて00および11のケース)が破棄されることが明らかであるため、メソッドを改善できるかどうか。

「von neumann trick biased」のグーグルは、問題に対するより良い解決策を開発するhttp://www.eecs.harvard.edu/~michaelm/coinflipext.pdf [この論文]を作成しました。 一度に2つのビットを使用するという考え方ですが、最初の2回の試行で00と11しか生成されない場合、0のペアを単一の0として扱い、1のペアを単一の1として扱い、フォンノイマンのトリックを適用しますこれらのペアに。 そして、それでもうまくいかない場合は、このレベルのペアで同様に組み合わせてください。

さらに、論文ではこれを発展させて、バイアスされたソースから複数の不偏ビットを生成し、本質的にビットペアからビットを生成する2つの異なる方法を使用し、これがビット数を正確に生成するという意味で最適であるというスケッチを提供します元のシーケンスにエントロピーが含まれていたこと。


4


https://en.wikipedia.org/wiki/Fair_coin#Fair_results_from_a_biased_coin [偏ったコインから公平なコインを生成する]への手順は、最初にhttps://en.wikipedia.org/wiki/John_von_Neumann[Von Neumann]に起因していました(数学と多くの関連分野で膨大な仕事をした人)。 手順は非常に簡単です。

  • コインを2回投げます。

  • 結果が一致したら、最初からやり直して両方の結果を忘れます。

  • 結果が異なる場合は、最初の結果を使用し、2番目の結果を忘れます。

このアルゴリズムが機能する理由は、HTを取得する確率が p(1-p)`であるためです。これは、THを取得することと同じです(1-p)p。 したがって、2つのイベントが同様に発生する可能性があります。

私もこの本を読んでいて、予想される実行時間を尋ねます。 2回のトスが等しくない確率は `z = 2 * p *(1-p)`であるため、予想される実行時間は `1 / z`です。

'' '' '

前の例は励みに見えます(結局、バイアスが「p = 0.99」のバイアスされたコインがある場合、コインを約50回投げる必要がありますが、それほど多くありません)。 だから、これは最適なアルゴリズムだと思うかもしれません。 残念ながらそうではありません。

Shannonの理論的限界(画像はこのhttps://cs.stackexchange.com/a/35223/27369[answer ])。 アルゴリズムは良好ですが、最適とはほど遠いことを示しています。

https://i.stack.imgur.com/F0808.png [image:https://i.stack.imgur.com/F0808.png [ここに画像の説明を入力]]

HHTTがこのアルゴリズムによって破棄されることを考慮する場合、改善を考え出すことができますが、実際にはTTHHと同じ確率を持っています。 したがって、ここで停止してHを返すこともできます。 HHHHTTTTなども同様です。 これらのケースを使用すると、予想される実行時間は改善されますが、理論的には最適化されません。

'' '' '

そして最後に-Pythonコード:

import random

def biased(p):
    # create a biased coin
    return 1 if random.random() < p else 0

def unbiased_from_biased(p):
    n1, n2 = biased(p), biased(p)
    while n1 == n2:
        n1, n2 = biased(p), biased(p)

    return n1

p = random.random()
print p

tosses = [unbiased_from_biased(p) for i in xrange(1000)]
n_1 = sum(tosses)
n_2 = len(tosses) - n_1
print n_1, n_2

これは一目瞭然です。結果の例を次に示します。

0.0973181652114
505 495

ご覧のとおり、「0.097」のバイアスがありましたが、ほぼ同じ数の「1」と「0」を取得しました


2


異なる値のシーケンスを取得するまで、RNGから_pairs_の値を描画する必要があります。 ゼロの後に1が続く、または1の後にゼロが続く。 次に、そのシーケンスの最初の値(または、問題ではない最後)を取得します。 (すなわち 描かれたペアが2つのゼロまたは2つの限り、繰り返します)

この背後にある数学は簡単です。0から1のシーケンスは、1から0のシーケンスと非常に同じ確率です。 常にこのシーケンスの最初(または最後)の要素を新しいRNGの出力として取得することにより、ゼロまたは1を取得する機会が均等に得られます。


1


おそらく最も効率的な方法ではありません。 一連の乱数を[0 …​、1、0 …​、1](0 …​ 1つ以上の0です)。 0の数を数えます。 最初のシーケンスが長い場合は0を生成し、2番目のシーケンスが長い場合は1を生成します。 (同じ場合は、もう一度試してください。)

これは、放射性粒子の崩壊から乱数を生成するためにHotBitsが行うことのようなものです。

_ 特定の減衰の時間はランダムであるため、2つの連続した減衰の間隔もランダムです。 次に、これらの間隔のペアを測定し、2つの間隔の相対的な長さに基づいてゼロまたは1ビットを出力します。 2つの減衰で同じ間隔を測定する場合、測定を破棄して再試行します _