我需要在半径为R的圆内生成一个均匀随机点。

我意识到,只要在区间[0…2π),且在区间(0…R)我最终会有更多的点指向中心,因为对于两个给定的半径,小半径内的点会比大半径内的点彼此更接近。

我在这里找到了一篇关于这个的博客文章,但我不明白他的推理。我认为这是正确的,但我真的很想知道他从哪里得到(2/R2)×r以及他如何得到最终解。


更新:在发布这个问题7年之后,关于平方根算法背后的数学问题,我仍然没有得到一个令人满意的答案。所以我花了一天时间自己写了一个答案。链接到我的答案。


当前回答

首先我们生成一个cdf[x]

一点到圆心的距离小于x的概率。假设圆的半径为R。

显然,如果x = 0,那么cdf[0] = 0

显然,如果x是R,则cdf[R] = 1

显然,如果x = r,则cdf[r] = (r^2)/(r^2)

这是因为圆上的每个“小区域”都有相同的被选中的概率,所以概率与问题区域成比例。距离圆心x的面积是r^2

所以cdf[x] = x^2/R^2因为两者相互抵消了

我们有cdf[x]=x^2/R^2其中x从0到R

我们解出x

R^2 cdf[x] = x^2

x = R Sqrt[ cdf[x] ]

现在我们可以用一个从0到1的随机数来替换cdf

x = R Sqrt[ RandomReal[{0,1}] ]

最后

r = R Sqrt[  RandomReal[{0,1}] ];
theta = 360 deg * RandomReal[{0,1}];
{r,theta}

我们得到极坐标 {0.601168 R, 311.915°}

其他回答

这里有一个快速而简单的解决方案。

在(0,1)范围内选择两个随机数,即a和b。如果b < a,则交换它们。你的观点是(b * R * cos(2 *π* a / b), b * R * sin(2 *π* a / b))。

您可以这样考虑这个解决方案。如果你把圆切开,然后把它拉直,你会得到一个直角三角形。把这个三角形缩小,你会得到一个从(0,0)到(1,0)到(1,1)再回到(0,0)的三角形,所有这些变换都会均匀地改变密度。你所做的就是在三角形中随机取一个点然后反过来得到圆中的一个点。

这取决于你对"均匀随机"的定义。这是一个微妙的点,你可以在这里的wiki页面上阅读更多关于它的内容:http://en.wikipedia.org/wiki/Bertrand_paradox_%28probability%29,在这里同样的问题,对“均匀随机”给出不同的解释会给出不同的答案!

根据你如何选择这些点,分布可能会有所不同,即使它们在某种意义上是均匀随机的。

It seems like the blog entry is trying to make it uniformly random in the following sense: If you take a sub-circle of the circle, with the same center, then the probability that the point falls in that region is proportional to the area of the region. That, I believe, is attempting to follow the now standard interpretation of 'uniformly random' for 2D regions with areas defined on them: probability of a point falling in any region (with area well defined) is proportional to the area of that region.

首先我们生成一个cdf[x]

一点到圆心的距离小于x的概率。假设圆的半径为R。

显然,如果x = 0,那么cdf[0] = 0

显然,如果x是R,则cdf[R] = 1

显然,如果x = r,则cdf[r] = (r^2)/(r^2)

这是因为圆上的每个“小区域”都有相同的被选中的概率,所以概率与问题区域成比例。距离圆心x的面积是r^2

所以cdf[x] = x^2/R^2因为两者相互抵消了

我们有cdf[x]=x^2/R^2其中x从0到R

我们解出x

R^2 cdf[x] = x^2

x = R Sqrt[ cdf[x] ]

现在我们可以用一个从0到1的随机数来替换cdf

x = R Sqrt[ RandomReal[{0,1}] ]

最后

r = R Sqrt[  RandomReal[{0,1}] ];
theta = 360 deg * RandomReal[{0,1}];
{r,theta}

我们得到极坐标 {0.601168 R, 311.915°}

我认为在这种情况下,使用极坐标是一种使问题复杂化的方法,如果你在一个边长为2R的正方形中随机选择点,然后选择点(x,y)使x^2+y^2<=R^2,这将会容易得多。

如何在半径为R的圆内随机生成一个点:

r = R * sqrt(random())
theta = random() * 2 * PI

(假设random()均匀地给出0到1之间的值)

如果你想把它转换成笛卡尔坐标,你可以做到

x = centerX + r * cos(theta)
y = centerY + r * sin(theta)

为什么sqrt(随机())?

让我们看看sqrt(random())之前的数学运算。为简单起见,假设我们是在单位圆上工作,即R = 1。

点与点之间的平均距离应该是相同的,不管我们看的距离中心有多远。这意味着,例如,观察一个周长为2的圆的周长,我们应该找到的点的数量是周长为1的圆周长上点的数量的两倍。


                

由于圆的周长(2πr)随r线性增长,因此随机点的数量应该随r线性增长。换句话说,期望的概率密度函数(PDF)线性增长。由于PDF的面积应该等于1,最大半径是1,我们有


                

所以我们知道随机值的理想密度应该是什么样的。 现在:当我们只有一个0到1之间的均匀随机值时,我们如何生成这样一个随机值?

我们用了一个叫做反变换采样的技巧

从PDF中创建累积分布函数(CDF) 沿着y = x镜像 将得到的函数应用于0到1之间的统一值。

听起来复杂吗?让我插入一段带有小侧轨的引语来传达直觉:

Suppose we want to generate a random point with the following distribution:                  That is 1/5 of the points uniformly between 1 and 2, and 4/5 of the points uniformly between 2 and 3. The CDF is, as the name suggests, the cumulative version of the PDF. Intuitively: While PDF(x) describes the number of random values at x, CDF(x) describes the number of random values less than x. In this case the CDF would look like:                  To see how this is useful, imagine that we shoot bullets from left to right at uniformly distributed heights. As the bullets hit the line, they drop down to the ground:                  See how the density of the bullets on the ground correspond to our desired distribution! We're almost there! The problem is that for this function, the y axis is the output and the x axis is the input. We can only "shoot bullets from the ground straight up"! We need the inverse function! This is why we mirror the whole thing; x becomes y and y becomes x:                  We call this CDF-1. To get values according to the desired distribution, we use CDF-1(random()).

所以,回到生成随机半径值,其中PDF等于2x。

步骤1:创建CDF: 由于我们处理的是实数,CDF表示为PDF的积分。

CDF(x) = ∫ 2x = x2

步骤2:沿y = x镜像CDF:

从数学上讲,这可以归结为交换x和y并求解y:

CDF: y = x2 交换:x = y2 解:y =√x CDF-1: y =√x

步骤3:将得到的函数应用于0到1之间的统一值

CDF-1(random()) =√random()

这就是我们要推导的:-)