如何平均得到圆内点的随机分布

今年某公司的笔试题目还蛮有意思的,原题不还没见到,不过经过一系列变化之后,可以等价地表述为如下:

如何利用一个能够返回平均随机点的函数,等概率地生成一个单位圆中的点,使得生成地点在圆内的分布概率尽量平均,即在面积上平均分布。

首先,要弄明白之间的平均随机是指什么;其次,还需要搞清楚在面积上平均分布是指什么。

下面两个图分别是平均随机和正态随机的分布情形:

左图中的随机算法是平均随机的,就是说生成的数字在区间内的每个区间的个数基本相同;

而右图中的随机算法是正态随机,看这个图形这个是就是以正态分布,分别是均值与方差。

下图是一个依靠平均分布产生的正方形分布,可以看出,这些点还是比较均匀的分布在正方形当中:

好了,下面来分析如果才能在圆内产生像正方形这样的随机分布,

聪明的孩子一般都会很快的想出算法1:

  1. 随机产生的矩形
  2. 如果 ,返回(x,y);否则,返回步骤1

这个算法其实就是从平均分布的正方形中扣出一个圆来做为返回(如下图),不过由于正方形的面积比较大,每次取点时,只有 的概率产生圆上的点(为圆的半径),所以运气差的时候,我们有可能会碰很多次尝试都无法得到一个圆上的点,这不确定性也使得这个算法看上去不那么可靠。

但其实,相对于运气,我们应该相信科学,其实连续3次取不到圆上的点的概率为,所以我们3次尝试可以取到圆上的点概率已经高达以上。总的说,这个方法虽不是最好,但无错,效率也不低。

利用的关系,不少同学会想到算法2:

1. 随机产生  的分布上的x,利用上述公式产生得到y的范围

2.随机产生一个  范围内的因子c,

这个就是一个随机点

但是,这个算法却不尽如人意,效果如下图:当靠近1时,由于的范围变小了,会变得很密集,不满足在圆的面积上平均分布的要求。

另一些人同学可能会想起极坐标的性质,一个角度加一个半径便可以唯一确认圆上的一点,于是便有了下面的算法3:

  1. 随机产生[0,360]上的一个角度
  2. 随机产生[0,1]上的一个半径,

这个点就是一个随机的圆上的点

实际里,这种算法也有一些问题,效果如下,问题很明显,由于点的半径上的随机分布,会使得靠近圆点附近的点显得过于密(因为这里面积比较小的缘故)。

最后,就是正解算法4

  1. 随机产生上的一个角度
  2. 随机产生  上的一个半径的平方,

这个点就是一个随机的圆上的点

可以看出,算法4与算法3基本上是相同的,唯一的区别就是算法3产生的是,而算法4中则是产生。而这一点点不同,也使得r的分布在r较大的地方点变得较密,抵消了面积变大的因素,变得平均,当然这只是简单的分析,相信会有牛人给大家来证明一下哈~ 最后,贴效果图,done!

update 这里补充某牛人对最后一种解法证明,感谢 Luliang同学 :)

http://wenku.baidu.com/view/de291225aaea998fcc220ef9.html








你可能感兴趣的:(算法导论)