クヌースがAJウォーカーに帰したエレガントなアルゴリズムがあります(Electronics Letters 10、8(1974)、127-128;ACMTrans。MathSoftware3(1977)、253-256)。
アイデアは、n個の異なる色の合計k * n個のボールがある場合、コンテナ番号が次のようにn個のコンテナにボールを分散させることができるということです。私は色iと多くても1つの他の色のボールを含んでいます。証明はnの帰納法によるものです。誘導ステップでは、ボールの数が最も少ない色を選択します。
あなたの例では、n =10です。確率に適切なmを掛けて、すべて整数になるようにします。したがって、おそらくm = 100で、色0のボールが20個、色1のボールが20個、色2のボールが10個、色3のボールが5個などです。つまり、k=10です。
次に、次元nのテーブルを生成します。各エントリは、確率(色iと他の色のボールの比率)と他の色です。
ランダムなボールを生成するには、[0、n)の範囲でランダムな浮動小数点数rを生成します。iを整数部分(rの床)とし、xを超過分(r – i)とします。
if (x < table[i].probability) output i
else output table[i].other
このアルゴリズムには、ランダムなボールごとに1回だけ比較するという利点があります。
例を考えてみましょう(Knuthと同じ)。
サイコロを投げるシミュレーションを検討してください。
したがって、P(2)= 1/36、P(3)= 2/36、P(4)= 3/36、P(5)= 4/36、P(6)= 5/36、P(7) = 6/36、P(8)= 5/36、P(9)= 4/36、P(10)= 3/36、P(11)= 2/36、P(12)=1/36。
36 * 11を掛けると、393個のボール、色2の11、色3の22、色4の33、…、色12の11が得られます。k= 393/11=36です。
Table [2] =(11/36、カラー4)
テーブル[12]=(11/36、カラー10)
表[3]=(22/36、色5)
テーブル[11]=(22/36、カラー5)
Table [4] =(8/36、カラー9)
テーブル[10]=(8/36、カラー6)
テーブル[5]=(16/36、カラー6)
テーブル[9]=(16/36、カラー8)
Table [6] =(7/36、カラー8)
Table [8] =(6/36、カラー7)
Table [7] =(36/36、カラー7)