8

最近別の質問に関連して尋ねられました:未知の長さのリストが与えられた場合、1回だけスキャンしてその中のランダムなアイテムを返します

すべきではないことはわかっていますが、そうすべきではない理由の標準的な説明に指を置くことはできません.

サンプルコードを見てください:

import random, sys

def rnd(): # a function that returns a random number each call
    return int(random.getrandbits(32))

class fixed: # a functor that returns the same random number each call
    def __init__(self):
        self._ret = rnd()
    def __call__(self):
        return self._ret

def sample(rnd,seq_size):
    choice = 0
    for item in xrange(1,seq_size):
        if (rnd() % (item+1)) == 0:
            choice = item
    return choice

dist = [0 for i in xrange(500)]
for i in xrange(1000):
    dist[sample(rnd,len(dist))] += 1
print "real",dist
print

dist = [0 for i in xrange(500)]
for i in xrange(1000):
    dist[sample(fixed(),len(dist))] += 1
print "reuse",dist

アイテムごとに新しい乱数を生成する適切なリザーバー サンプリングの選択肢は、次のように適切に均等に分散されます。

real [1, 3, 0, 1, 2, 3, 2, 3, 1, 2, 2, 2, 2, 0, 0, 1, 3, 3, 4, 0, 2, 1, 2, 1, 1, 4, 0, 3, 1, 1, 2, 0, 0, 0, 1, 4, 6, 2, 3, 1, 1, 3, 2, 1, 3, 3, 1, 4, 1, 1, 2, 2, 5, 1, 2, 1, 0, 3, 1, 0, 2, 6, 1, 2, 2, 1, 1, 1, 1, 3, 2, 1, 5, 4, 0, 3, 3, 4, 0, 0, 2, 1, 3, 2, 3, 0, 2, 4, 6, 3, 0, 1, 3, 0, 2, 2, 4, 3, 2, 1, 2, 1, 2, 2, 1, 4, 2, 0, 0, 1, 1, 0, 1, 4, 2, 2, 2, 1, 0, 3, 1, 2, 1, 0, 2, 2, 1, 5, 1, 5, 3, 3, 1, 0, 2, 2, 0, 3, 2, 3, 0, 1, 1, 3, 0, 1, 2, 2, 0, 1, 2, 2, 3, 2, 3, 1, 1, 0, 1, 2, 2, 2, 2, 2, 3, 2, 1, 2, 2, 2, 1, 3, 3, 1, 0, 1, 1, 0, 1, 3, 2, 1, 4, 3, 4, 1, 1, 1, 2, 1, 2, 0, 0, 0, 1, 1, 2, 6, 0, 1, 1, 0, 1, 0, 1, 2, 2, 3, 0, 1, 2, 2, 1, 0, 4, 2, 1, 2, 2, 0, 4, 4, 0, 3, 2, 2, 1, 2, 4, 1, 2, 1, 0, 2, 1, 1, 5, 1, 2, 2, 3, 2, 3, 0, 1, 2, 3, 2, 5, 2, 3, 0, 1, 1, 1, 1, 3, 4, 2, 4, 1, 2, 3, 2, 5, 2, 1, 0, 1, 1, 2, 2, 3, 1, 1, 1, 2, 1, 2, 0, 4, 1, 1, 2, 3, 4, 3, 1, 2, 3, 3, 3, 2, 1, 2, 0, 0, 4, 3, 2, 2, 5, 5, 3, 3, 3, 1, 0, 1, 3, 1, 1, 2, 4, 3, 1, 4, 4, 2, 5, 0, 5, 4, 2, 1, 0, 4, 1, 3, 3, 2, 4, 2, 3, 3, 1, 3, 3, 4, 2, 2, 1, 1, 1, 1, 3, 3, 5, 3, 2, 4, 0, 1, 3, 2, 2, 4, 2, 2, 3, 4, 5, 3, 2, 1, 2, 3, 2, 2, 2, 4, 4, 0, 1, 3, 3, 3, 4, 1, 2, 4, 0, 4, 0, 3, 2, 1, 1, 4, 2, 1, 0, 0, 0, 4, 2, 2, 1, 4, 3, 1, 1, 3, 2, 4, 3, 4, 2, 1, 1, 2, 2, 3, 3, 1, 2, 2, 1, 1, 2, 3, 1, 9, 1, 3, 4, 2, 4, 4, 0, 1, 0, 1, 0, 2, 1, 0, 1, 2, 3, 3, 6, 2, 2, 1, 2, 4, 3, 3, 3, 2, 1, 2, 1, 2, 8, 2, 3, 1, 5, 3, 0, 2, 1, 1, 4, 2, 2, 1, 2, 3, 2, 1, 0, 4, 3, 4, 3, 1, 3, 2, 3, 2, 2, 1, 0, 1, 2, 5, 3, 0, 3, 1, 2, 2, 2, 1, 0, 1, 4]

一方、すべてのアイテムに同じ乱数を再利用すると、非常に低い数値に偏った分布が得られます。

reuse [92, 50, 34, 19, 23, 16, 13, 9, 9, 9, 11, 10, 6, 7, 8, 5, 5, 6, 4, 2, 2, 3, 2, 3, 3, 6, 6, 1, 4, 3, 5, 2, 2, 1, 1, 2, 3, 4, 3, 4, 1, 3, 1, 0, 0, 1, 5, 3, 1, 2, 0, 2, 0, 1, 1, 6, 2, 0, 2, 2, 4, 2, 2, 0, 2, 2, 2, 0, 3, 0, 4, 1, 2, 1, 4, 2, 2, 0, 1, 0, 1, 1, 0, 0, 0, 2, 0, 0, 2, 0, 0, 1, 0, 0, 1, 0, 2, 0, 0, 1, 2, 1, 3, 1, 0, 1, 2, 0, 4, 3, 0, 0, 2, 0, 0, 1, 0, 0, 2, 0, 2, 1, 0, 1, 0, 0, 1, 1, 3, 0, 1, 1, 0, 2, 0, 1, 2, 0, 1, 1, 4, 1, 1, 1, 2, 1, 0, 1, 2, 0, 2, 1, 1, 2, 0, 1, 1, 0, 2, 0, 2, 0, 0, 2, 0, 1, 0, 2, 1, 1, 0, 0, 1, 2, 4, 1, 0, 2, 0, 1, 2, 1, 3, 0, 1, 0, 0, 1, 0, 0, 2, 1, 0, 0, 0, 3, 2, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 4, 1, 0, 2, 1, 0, 0, 2, 1, 1, 3, 3, 2, 0, 1, 0, 2, 0, 1, 1, 0, 0, 3, 1, 0, 0, 1, 0, 3, 2, 2, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2, 0, 4, 1, 0, 0, 2, 0, 1, 1, 0, 0, 3, 1, 3, 2, 2, 1, 3, 1, 2, 0, 1, 1, 3, 0, 3, 1, 2, 0, 2, 0, 2, 0, 3, 0, 3, 0, 3, 1, 0, 2, 3, 1, 1, 0, 1, 3, 3, 1, 1, 1, 0, 2, 1, 1, 4, 1, 1, 1, 2, 0, 3, 1, 1, 0, 4, 1, 1, 0, 1, 3, 1, 0, 1, 1, 0, 3, 3, 0, 2, 4, 0, 1, 2, 1, 6, 1, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 4, 2, 0, 1, 2, 0, 1, 4, 1, 2, 0, 5, 2, 2, 0, 6, 2, 2, 1, 3, 0, 3, 1, 1, 0, 3, 1, 4, 2, 0, 1, 0, 1, 2, 3, 1, 1, 3, 0, 0, 0, 1, 1, 4, 3, 3, 0, 0, 1, 0, 1, 1, 2, 1, 0, 2, 1, 4, 5, 1, 1, 3, 0, 1, 1, 1, 3, 1, 1, 0, 3, 3, 1, 3, 0, 1, 0, 0, 1, 1, 3, 2, 1, 0, 3, 1, 1, 3, 1, 3, 1, 2, 2, 2, 0, 0, 5, 1, 3, 0, 1, 4, 1, 1, 1, 3, 2, 1, 3, 2, 1, 3, 1, 2, 2, 3, 2, 2, 1, 0, 3, 3, 1, 3, 3, 3, 2, 1, 2, 3, 3, 3, 1, 2, 2, 2, 4, 2, 1, 5, 2, 2, 0]

ここの数学は何ですか?同じ乱数を再利用できないのはなぜですか?

4

3 に答える 3

7

編集、コメントに応じて:

リザーバー サンプリング機能する方法は次のとおりです。同じ確率で追加のビンを作成するために、既存のビンのそれぞれから正確に適切な割合のサンプルを選択する必要があります。ビンの 1 つをランダムにサンプリングした場合、sample()ループ内で確率でitemビンからサンプルを選択する必要があります。1/(item + 1)

ただし、 ではfixed()、選択の決定と前のビン番号の両方が、同じ固定 32 ビット番号に依存します。これは、各ビンからサンプルが削除される可能性が均一ではないことを意味します。


ループの 3 回目の繰り返しで何が起こるかを考えてみましょうsample()。既存の 3 つのビン (0、1、および 2) があり、それぞれのサンプルの 1/4 を選択して、新しく作成したビン 3 に追加します。

ビン 1のすべての 32 ビットfixed()数は偶数になり (最初のパスで 2 で割り切れるすべての数が選択されたため)、ビン 0 のすべての数は奇数になることに注意してください (偶数がビン 1 に移動されたため)。2 番目のパスは、3 で割り切れるすべての数値をビン 2 に移動します (これまでのところ問題なく、ビン 0 と 1 の偶数/奇数の除算は変更されません)。

3 番目のパスはfixed()、4 で割り切れるすべての数値をビン 3 に移動します。すべて奇数)。そのため、新しいビンの予想されるサイズは正しいはずですが、古いビンの予想されるサイズはもはや同じではありません。

これがfixed()不均一な分布を生成する方法です。乱数を選択することで各ビンの正確な割合を選択できるという暗黙の仮定は、その数が元のビンの選択に使用された数値に予測可能な方法で依存する場合、違反します。


乱数の基本的な特性は、統計的な意味で、各サンプルが前のサンプルから独立して分散されなければならないということです。乱数に基づくアルゴリズムは、このプロパティに依存します。

疑似乱数ジェネレーター (PRNG) は、実際にはランダムではありません。ご存知のように、それらの結果は実際には固定されたシーケンスです。PRNG の結果は、ほとんどの目的で実際の乱数のように振る舞うように意図的にスクランブルされます。ただし、PRNG が特定のアプリケーションに対して「弱い」場合、PRNG の内部動作がアプリケーションの詳細と奇妙な方法で相互作用し、非常にランダムでない結果になる可能性があります。

ここで試しているのは、同じ乱数を再利用して悪い PRNG を構築することです。実際の結果は、アプリケーションが乱数をどのように使用するかの詳細に依存します...

は意図的に破損した PRNGですfixed()が、多くの商用ライブラリ PRNG は「脆弱」であり、一部のアプリケーションと同様の奇妙な相互作用が発生する可能性があります。実際問題として、「弱さ」はアプリケーションに関連しています。また、弱い PRNG を明らかにするために広く使用されている統計テストがありますが、アプリケーションが偶数の奇妙な相関関係につまずかないという保証はありません。 「強い」PRNG。

于 2012-01-02T20:23:22.847 に答える
1

毎回乱数を選ぶと、ストリームからの次のアイテムは、前に選んだアイテムよりも 1/CURRENTSIZE の確率で勝ってしまいます。

では、ストリームごとに 1 つの乱数の問題は何でしょうか? なぜ分布を歪めるのですか?

まだ完全な答えは見つかっていませんが、アイデアはあります。

たとえば、100 個の数字のストリームから乱数 0...999 を選んでみましょう。次に、2 番目の項目の観点から見てみましょう。

いつ勝つの?まず、N%2==0 である必要があります。したがって、偶数でなければなりません。また、ストリーム内の 2 の各倍数の 1 つおきの倍数、4...6...8....10 などによっても打ち負かされます。しかし、たとえば 106 で勝ちます。

それが勝つすべての数字を計算すると、0..999 で、81 回になります!

ここで 4 を取りましょう。これは N%4==0 である必要があり、4 のすべての倍数から N (8...12....16) で打ち負かされます。4が何回勝てるか計算すると45回…!したがって、分配は公平ではありません。

これは、乱数をストリームのサイズの最大値にすると修正できます。その後、すべてに勝つチャンスが 1 つあり、再び均等な分布になります。

たとえば、ストリーム サイズが 100 で、0..199 の乱数を選択するとします。最初の 100 個の乱数はすべて正確に 1 つの一致があることがわかっているため、それらは均等に分散されます。しかし、乱数 99...199 ではどうなるでしょうか? 分布は均等ではありません!たとえば、101 は 1 に対して 101%X==0 のみを返します。これはすべての素数 (101、103、107、109、113、127、131、137、139、149、151、157、163、 167, 173, 179, 181, 191, 193, 197, 199)。そのため、アイテム 1 は他のアイテムよりも勝つチャンスがはるかに大きくなります。

これは、アイテムごとに新しい乱数を選択する場合には当てはまりません。その場合、チャンスを追加できます。たとえば、アイテム 1 が登場した場合、次のような当選確率があります。

NOT(1/2 + 1/3 + 1/4 + 1/5 + 1/6 (...など))

于 2012-02-15T12:07:24.553 に答える
0

これについて考えてみてください: 固定数が非常に小さい場合はどうなりますか?

于 2012-01-12T11:43:29.527 に答える