2012-10-25 94 views
6

可能重複:
Create random number within an annulus生成的環(環)內的均勻隨機點

我想的annulus內獲得均勻地獲得的隨機點,即,所述該區域位於半徑爲R1的圓內,但位於半徑爲R2的圓圈之外,其中R1 > R2和兩個圓都位於同一點上。我想避免使用拒絕抽樣。

如果可能,我希望解決方案類似於this one-用於計算圓圈內的隨機點 - 我發現它非常優雅和直觀。也就是說,我也想避免使用平方根

+0

感謝您的編輯,不知道面積稱爲環。 ;-) –

+0

補充澄清,指出我想避免平方根(因此,不完全是另一個的重複)。 –

+0

我想讓它變成你在[R1,R2]鏈接問題中改變'[0,R]'的情況,但我敢打賭這並不那麼簡單。或者是? – AakashM

回答

2

編輯:請注意,此解決方案可能不統一。請參閱下面的Mark Dickinson的評論。

好吧,我覺得我明白了。請注意,該解決方案在this answer中受到很大啓發,並且r1 = R1/R1和r2 = R2/R1。

僞代碼:

t = 2*pi*random() 
u = random()+random() 
r = if u>1 then 2-u else u 
r = if r<r2 then r2+r*((R1-R2)/R2) else r 
[r*cos(t), r*sin(t)] 

這是數學。

f[] := Block[{u, t, r}, u = Random[] + Random[]; 
r1 = 1; r2 = 0.3; 
t = Random[] 2 Pi; 
r = If[u > 1, 2 - u, u]; 
r = If[r < r2, r2 + r*((R1 - R2)/R2), r]; 
{r Cos[t], r Sin[t]}] 

ListPlot[Table[f[], {10000}], AspectRatio -> Automatic] 

Distribution of the simple algorithm

它所做的是重新映射全部落入圓圈內進入環的數字,均勻地分散它們。如果有人發現此解決方案的一致性問題,請發表評論。

比較這個其他的解決辦法找到here

Distribution of the sqrt algorithm

+4

這是一個整潔的答案,但不幸的是結果並不統一。如果嘗試使用例如「R2 = 0.95」和「R1 = 1.0」,則會看到靠近環外的點更受歡迎。生成一個合適的'r'的正確方法是在'[R2,R1]'和'v'中統一選擇'u',隨機變量'u'和'v'選擇''[0,R2 + R1 ]',如果'v = u'則取'r = u'。 –

+0

馬克,感謝您的評論和您的選擇。你確定我的解決方案是不一致的嗎?我無法注意到它,即使在R2 = 0.95的情況下也是如此:http://i.imgur.com/wmDEo.png –

+0

很確定,是的。 :-)下面是一個你可以做的測試:取R2 = 0.5和R1 = 1.0,併產生10,000個樣本(比如說)。現在通過添加一個半徑爲0.75的圓來將環分爲兩部分,並計算您生成的樣本中有多少位於外環中(0.75 <=半徑<= 1.0),內環中有多少(0.5 <=半徑<= 0.75)。如果溶液是均勻的,你應該得到接近7/5 = 1.4的比值(外環面積= 7/16 pi;內環面積= 5/16 pi)。我還沒有測試過,但我預測你的解決方案會提供接近5/3 = 1.66666的比率...... –

-1

最簡單的方法是使用rejection sampling。在邊長2 * R2的正方形中均勻地生成大量點,然後將這些樣本過濾到外部圓內而不是內部圓中。

不漂亮或高效,但在大多數情況下,已足夠。

+2

他說他不想使用拒收抽樣。而對於拒絕抽樣,至少可以從他所鏈接的方法開始,在較大的圓圈中統一點。 –

1

它很容易。使用極座標,即爲角度值theta生成一個隨機值,併爲距離原點的距離生成一個。由於你的圈子都在同一個起源,這很容易。

但是注意:你可以通過一個統一的隨機函數來生成theta值,這很好,但是對於你不能這麼做的距離,因爲這樣點就會聚集在原點周圍。 你必須考慮到圓的周長在^ 2增長(你必須使用平方根的倒數)。

使用統一分佈的隨機函數rnd(0..1)這將是這樣的:

theta = 360 * rnd(); 
dist = sqrt(rnd()*(R1^2-R2^2)+R2^2); 

編輯:對於轉化爲笛卡爾座標,你剛纔計算:

x = dist * cos(theta); 
y = dist * sin(theta); 
+0

我懷疑典型的'cos'和'sin'函數需要度數,更可能是弧度。但這是一種工作方法。 –

+0

如果可能的話,我想避免sqrt()像我在鏈接的答案。我也不想使用拒絕抽樣。 –

+0

影響你的功能。如果你不使用度數而是弧度,只需將360替換爲2 * PI – flolo