半径Rの円内にランダムな点を生成する方法:
r = R * sqrt(random())
theta = random() * 2 * PI
(仮定するとrandom()
、0と1の間の値が均一に与えられます)
これをデカルト座標に変換したい場合は、
x = centerX + r * cos(theta)
y = centerY + r * sin(theta)
なんでsqrt(random())
?
に至るまでの数学を見てみましょうsqrt(random())
。簡単にするために、単位円、つまりR = 1で作業していると仮定します。
ポイント間の平均距離は、中心からどれだけ離れていても同じでなければなりません。これは、たとえば、円周2の円の外周を見ると、円周1の円の外周にあるポイントの数の2倍のポイントを見つける必要があることを意味します。
円(2πの円周のでrが)とともに直線的に成長するR、ランダムな点の数と共に直線的に成長する必要があることを、以下、R。言い換えると、望ましい確率密度関数(PDF)は直線的に増加します。PDFの面積は1で、最大半径は1であるため、次のようになります。
これで、ランダム値の望ましい密度がどのようになるかがわかります。さて:0と1の間の一様なランダム値だけがある場合、どのようにしてそのようなランダム値を生成しますか?
逆変換サンプリングと呼ばれるトリックを使用します
- PDFから、累積分布関数(CDF)を作成します。
- これをy = xに沿ってミラーリングする
- 結果の関数を0と1の間の均一な値に適用します。
複雑に聞こえますか?直感を伝える小さなサイドトラックを含むブロッククォートを挿入します。
次の分布を持つランダムポイントを生成するとします。
あれは
- 1と2の間の点の1/5
- ポイントの4/5は、2〜3の間で均一です。
CDFは、名前が示すように、PDFの累積バージョンです。直感的に:PDF(x)はxでのランダム値の数を表しますが、CDF(x)はxより小さいランダム値の数を表します。
この場合、CDFは次のようになります。
これがどのように役立つかを確認するために、均一に分布した高さで左から右に弾丸を発射すると想像してください。弾丸が線に当たると、それらは地面に落ちます:
地上の弾丸の密度がどのように私たちの望ましい分布に対応しているかを見てください!もうすぐ着きます!
問題は、この関数では、y軸が出力で、x軸が入力であるということです。「地面から弾丸を真っ直ぐに発射する」ことしかできません!逆関数が必要です!
これが、すべてをミラーリングする理由です。xはyになり、yはxになります。
これをCDF -1と呼びます。希望の分布に従って値を取得するには、CDF -1(random())を使用します。
…つまり、PDFが2 xに等しいランダムな半径値を生成することに戻ります。
ステップ1:CDFを作成する:
実数で作業しているため、CDFはPDFの積分として表されます。
CDF(x)=∫2 x = x 2
ステップ2:y = xに沿ってCDFをミラーリングします。
数学的にこれは、xとyを入れ替えてyを解くことに要約されます。
CDF: Y = X 2
スワップ: X = Y 2
解く: Y =√ X
CDF -1: Y =√ X
ステップ3:結果の関数を0と1の間の均一な値に適用する
CDF -1(random())=√random()
これは、私たちが導き出したものです:-)