要求: 在半径为1的圆内,实现在圆内随机均匀地取一点,返回点的[x,y]
1. 拒绝采样法(蒙特卡洛方法)
在圆的外切正方形内生成随机点,然后判断点是否在圆内,如果不在圆内就舍弃掉,直到生成在圆内的点就返回。
代码
function getPoint() {
while (true) {
// 生成[-1, 1]范围随机的x,y坐标
const x = Math.random() * 2 - 1;
const y = Math.random() * 2 - 1;
if (x * x + y * y <=1) {
return [x, y];
}
}
}
2. 极坐标加密度函数
极坐标的做法是随机产生半径 R 和角度 thetaθ, 其中随机变量 thetaθ 是符合均匀分布的,但是R不符合均匀分布,直观来看,在圆的面积中,同一半径的点出现在一个圆周上,因此半径 x 出现的概率应该是周长除以面积。据此可写出概率密度函数
f(x)如下,其中 r 为最大半径:
若已知随机变量的概率分布函数 F(x),y 是 [0,1] 区间的均匀分布随机数,则具有概率分布函数 F(x) 的随机数可以用下式得到:x=F^-1(y)。
简单来说,要得到随机分布可以按照以下步骤:
- 求出概率分布函数 F(x)
- 求概率分布函数的反函数 F^-1(x)
- 把 [0,1]区间内均匀分布的随机数代入 x = F^-1(y)
代码:
function getPoint2() {
const theta = Math.random() * 2 * Math.PI;
const r = Math.random();
const x = Math.sin(theta) * Math.sqrt(r);
const y = Math.cos(theta)* Math.sqrt(r);
return [x, y];
}