n
単語と頻度のペアの配列が与えられた場合:
[ (w 0 , f 0 ), (w 1 , f 1 ), ..., (w n-1 , f n-1 ) ]
ここで、 は単語、は整数の周波数、周波数の合計、wi
fi
∑fi = m
任意の単語を選択する確率がその頻度に比例するように、擬似乱数ジェネレータ (pRNG) を使用してp
単語を選択したいと考えています。wj0, wj1, ..., wjp-1
P(w i = w j k ) = P(i = j k ) = f i / m
(これは置換を伴う選択であるため、毎回同じ単語が選択される可能性があることに注意してください)。
これまでに 3 つのアルゴリズムを考え出しました。
サイズ の配列を作成し
m
、最初のエントリが、次のエントリが、というように、最後のエントリがになるように入力します。f0
w0
f1
w1
fp-1
wp-1
[ w 0 , ..., w 0 , w 1 ,..., w 1 , ..., w p-1 , ..., w p-1 ]
次に、pRNG を使用p
して範囲内のインデックスを選択し0...m-1
、それらのインデックスに格納されている単語を報告します。n よりもはるかに大きくなる可能性があるため、
これには手間がかかります。O(n + m + p)
m
入力配列を 1 回ステップ実行し、計算します。
m i = ∑ h≤i f h = m i-1 + f i
を計算した後、pRNG を使用して のそれぞれの範囲内の数値を生成し、 for を選択します(場合によっては の現在の値を置き換えます) 。 これには作業が必要です。mi
xk
0...mi-1
k
0...p-1
wi
wjk
wjk
xk < fi
O(n + np)
- アルゴリズム 2 のように計算し、n 個の単語-頻度-部分和のトリプルで次の配列を生成します。
mi
[ (w 0 , f 0 , m 0 ), (w 1 , f 1 , m 1 ), ..., (w n-1 , f n-1 , m n-1 ) ]
次に、各 k in0...p-1
について、pRNG を使用して範囲内の数値を生成し、トリプルの配列でバイナリ検索を実行してstを見つけ、 forを選択します。 これには作業が必要です。xk
0...m-1
i
mi-fi ≤ xk < mi
wi
wjk
O(n + p log n)
私の質問は次のとおりです。これに使用できるより効率的なアルゴリズムはありますか、それともこれほど優れていますか?