重み付き乱数について
理解を助けるために、まず 3 種類のランダム問題の比較を見てみましょう:
1. n 個のレコードがあり、それらから m 個のレコードを選択します。選択されたレコードの順序は無視されます。 。
実装のアイデア: すべてのレコードを行ごとにスキャンし、n/m 個のレコードごとに 1 つのデータを取得します
2。タイプ 1 の場合、選択された m 個のレコードがランダムに並べ替えられることも必要です
実装のアイデア: n 個のレコードを指定し、それぞれマーカーの列であり、値は 1 ~ n の間でランダムに選択された重複しないデータです。
3. タイプ 1 および 2 の問題とは異なり、レコードに重みがある場合、重みに基づいてレコードをランダムに選択する方法。 たとえば、A の重みが 10、B の重みが 5、C の重みが 1 である場合、4 つがランダムに選択されると、おそらく AABB が表示されるはずです。
3 番目のタイプの質問がこの記事の焦点です。
実装アイデア: 例として、A:10、B:5、C:1 からランダムに選択された 4 つのレコードを取り上げます (重みでソートされているかどうかは関係ありません)
オフ次のように、n 行の値が n 番目の行と n-1 番目の行に割り当てられ、再帰的に実行されます:
A 10
B 15
C 16
次に、次からランダムに数値を選択します。毎回 [1,16]、[1,10] に該当する場合は A を選択し、(10,15] の間に該当する場合は B を選択し、(16,16] の間に該当する場合は C を選択します)。以下、より大きな間隔を占める人 (重みが高い) が選択される確率が高くなります
宝くじやゲームの爆発装置での使用
必要に応じて各アイテムの出現確率を設定する操作です 今日説明する加重ランダム アルゴリズムの考え方は非常にシンプルです。つまり、「すべてのアイテムは重みに応じて区間が形成され、重みが大きい区間が大きくなります。次に、サイコロを振って、どの範囲に収まるかを確認します。たとえば、年末があります。抽選で、アイテムは iPhone/ipad/itouch です。
主催者によって設定された重みは [('iphone', 10), (' ipad', 40), ('itouch', 50)] です。 アイデアは次のとおりです。これは、random.choice(['iphone']*10 + ['ipad']*40 + ['itouch' ]*50) という 1 行のコードで説明できます。
以下、一般的な関数として記述します。 .
#coding=utf-8 import random def weighted_random(items): total = sum(w for _,w in items) n = random.uniform(0, total)#在饼图扔骰子 for x, w in items:#遍历找出骰子所在的区间 if n<w: break n -= w return x print weighted_random([('iphone', 10), ('ipad', 40), ('itouch', 50)])