最近遇到乙個問題,需要在以乙個座標為中心的區域內生成一組均勻分布的隨機點,首先想到的就是以圓作為區域。
根據\(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...