圓內的均勻隨機點

2022-03-08 02:54:06 字數 4477 閱讀 4903

最近遇到乙個問題,需要在以乙個座標為中心的區域內生成一組均勻分布的隨機點,首先想到的就是以圓作為區域。

根據\(x^+y^=r^\),那麼自讓想到可以先隨機生成[-r,r]間的橫座標x,然後生成[\(-\sqrt-x^},\sqrt-x^}\)]範圍內的隨機數y,那麼(x,y)自然也就是在圓內的隨機點了。

寫一段**看一看:

看到這個圖應該立刻就知道**出錯了,當x越靠近圓的邊緣的話,y的範圍就會越小,所以兩邊邊緣的點會非常密集,不能算"均勻分布"。

然後就會想到能否利用面積這個概念呢?因為上乙個方法出錯在邊緣處,即y的範圍會隨著x的範圍的變化而發生變化,所以如果在乙個矩形區域內生成隨機點,就會是均勻分布的;然後如果在圓內就保留下來這個點:

def random_point_in_circle(point_num, radius):

for i in range(2,point_num+1):

while true:

x=random.uniform(-radius,radius)

y=random.uniform(-radius,radius)

if(x**2)+(y**2)

break

plt.plot(x,y,'*',color="blue")

def main():

pi = np.pi

theta = np.linspace(0, pi * 2, 1000)

r = 1

x = np.sin(theta) * r

y = np.cos(theta) * r

plt.figure(figsize=(6, 6))

plt.plot(x, y, label="cycle", color="green", linewidth=2)

plt.title("random_points_in_circle")

random_point_in_circle(4000, r)

plt.legend()

plt.show()

if __name__=="__main__":

main()

效果很ok:

但是這種方法的缺點就是會有較大的開銷,想想看我們是按矩形範圍內產生的點,最後會在圓內的點的概率只有\(\frac}}=\frac\)

那麼我們能否考慮用極座標呢,可以消除y的範圍對x的範圍敏感的問題。利用\(x=r*cos(\theta)​\)與\(y=r*sin(\theta)​\),先隨機生成[\(0,2\pi​\)]內的\(\theta​\),然後隨機生成[0,r]內的r:

def random_point_in_circle(point_num, radius):

for i in range(2,point_num+1):

theta=random.random()*2*np.pi

r=random.uniform(0,radius)

x=r*math.cos(theta)

y=r*math.sin(theta)

plt.plot(x,y,'*',color="blue")

def main():

pi = np.pi

theta = np.linspace(0, pi * 2, 1000)

r = 1

x = np.sin(theta) * r

y = np.cos(theta) * r

plt.figure(figsize=(6, 6))

plt.plot(x, y, label="cycle", color="green", linewidth=2)

plt.title("random_points_in_circle")

random_point_in_circle(4000, r) # 修改此處來顯示不同演算法的效果

邊緣的點會比較稀疏的原因是這樣的,由於r是在[0,r]之間等概率產生的,所以可以認為同乙個r的生成的隨機點是相同的,但是圓的半徑會變大,同樣數量的點就會顯得稀疏了。

在這裡我們先引入一條定理:令\(r=r^\),r在[0,1]上是均勻分布,\(\theta\)在[\(0,2\pi\)]上是均勻分布,且r與\(\theta\)相互獨立,令$$x=rcos(\theta)=\sqrtcos(\theta)$$

\[y=r*sin(\theta)=\sqrt*sin(\theta)

\]那麼我們有(x,y)是均勻分布。

如果要證明(x,y)是均勻分布,由對稱性我們只需要證明(x,y)在第一象限為均勻分布即可,即需要證明(x,y)的聯合概率密度\(f(x,y)=\frac=\frac\)

首先我們知道連續性隨機向量變換的聯合分布的乙個定理:

設(x,y)是聯合概率密度為\(f(x,y)\)的連續性隨機向量,\(g_(x,y),g_(x,y)\)

\(\xi=g_(x,y), \eta=g_(x,y)\)。如果對任何非負連續的二元函式\(h(\mu,\upsilon)\)成立,則有:

放上**:

def random_point(car_num,radius):

for i in range(1, car_num + 1):

theta = random.random() * 2 * np.pi

r = random.uniform(0, radius)

x = math.cos(theta) * (r ** 0.5)

y = math.sin(theta) * (r ** 0.5)

plt.plot(x, y, '*', color="blue")

def main():

pi = np.pi

theta = np.linspace(0, pi * 2, 1000)

r = 1

x = np.sin(theta) * r

y = np.cos(theta) * r

plt.figure(figsize=(6, 6))

plt.plot(x, y, label="cycle", color="green", linewidth=2)

plt.title("random_points_in_circle")

random_point(4000, r) # 修改此處來顯示不同演算法的效果

plt.legend()

plt.show()

if __name__=="__main__":

main()

結果如下:

應該是比較滿意的了。

演算法 均勻的生成圓內的隨機點

演算法 1 設半徑為 r x r ast cos theta y r ast sin theta 其中 0 leqslant r leqslant r t 為0 1均勻分布產生的隨機數,r sqrt t ast r theta 2 pi ast t,t sim u 0,1 證明 url 下面的演算法...

leetcode在圓內隨機生成點

1.拒絕取樣 在乙個半徑為r的圓內均勻隨機生成點,可以使用拒絕取樣 rand rand max隨機產生0 1之間的數,設其值為x,則2 x 1隨機產生 1 1之間的數 則 2 x 1 r則隨機產生 r r之間的數 對於y同理 如下 class solution vectorrandpoint you...

478 在圓內隨機生成點

題目描述 給定圓的半徑和圓心的 x y 座標,寫乙個在圓中產生均勻隨機點的函式 randpoint 說明 輸入值和輸出值都將是浮點數。圓的半徑和圓心的 x y 座標將作為引數傳遞給類的建構函式。圓周上的點也認為是在圓中。randpoint 返回乙個包含隨機點的x座標和y座標的大小為2的陣列。示例 1...