题目
给定圆的半径和圆心的位置,实现函数 randPoint
,在圆中产生均匀随机点。
实现 Solution
类:
Solution(double radius, double x_center, double y_center)
用圆的半径radius
和圆心的位置(x_center, y_center)
初始化对象randPoint()
返回圆内的一个随机点。圆周上的一点被认为在圆内。答案作为数组返回[x, y]
。
示例 1:
输入:["Solution","randPoint","randPoint","randPoint"]
[[1.0, 0.0, 0.0], [], [], []] 输出: [null, [-0.02493, -0.38077], [0.82314, 0.38945], [0.36572, 0.17248]]
解释:
Solution solution = new Solution(1.0, 0.0, 0.0);
solution.randPoint ();//返回[-0.02493,-0.38077]
solution.randPoint ();//返回[0.82314,0.38945]
solution.randPoint ();//返回[0.36572,0.17248]
提示:
- \(0 < radius <= 10^{8}\)
- \(-10^{7} <= x_center, y_center <= 10^{7}\)
randPoint
最多被调用 \(3 * 10^{4}\) 次
标签
几何, 数学, 拒绝采样, 随机化
相似题目
题解
拒绝采样
简单的想法:在 \(x\) 轴和 \(y\) 轴分别均匀采样,但这样得到的数不一定会在圆内,如下图所示,有可能会随机到蓝色部分。
最简单的处理方法是,检查一下随机出的点在不在圆中,不在的话就重新再采样一次,直到成功随机出结果。
经典的蒙特卡洛方法就是通过随机投点的方法计算圆的圆周率的,我们也很容易根据几何概型计算出随机投点落在圆内的概率为 \(\dfrac{\pi}{4}\), 并且落在圆内任意一点也是随机的。
期望投点次数可以通过全概率公式计算:
\[ \begin{aligned} E &= \sum\limits_{k=1}^\infty k \times \dfrac{\pi}{4} \times (1 - \dfrac{\pi}{4})^{k - 1} \\ &= \dfrac{\pi}{4} \sum\limits_{k=1}^\infty k \times (1 - \dfrac{\pi}{4})^{k - 1} \\ &= \dfrac{\pi}{4} (\sum\limits_{k=1}^\infty \int k \times x^{k - 1} dx)^{'}_{x=1 - \frac{\pi}{4}} \\ &= \dfrac{\pi}{4} (\sum\limits_{k=1}^\infty x^{k})^{'}_{x=1 - \frac{\pi}{4}} \\ &= \dfrac{\pi}{4} (\dfrac{1}{1 - x})^{'}_{x=1 - \frac{\pi}{4}} \\ &= \dfrac{\pi}{4} \dfrac{1}{(1 - x)^2} |_{x=1 - \frac{\pi}{4}} \\ &= \dfrac{4}{\pi} \end{aligned} \]
其中等号 3-6 使用了泰勒展开的微积分变换,由期望和概率我们可以推测,几乎绝大多数采样都会在 1 ~ 2 次内取得,这个结果是可以接受的。
1 | # Code language: Python |
1 | // Code language: Cpp |
1 | // Code language: Java |
- 时间复杂度: \(O(\dfrac{4}{\pi})\)
- 空间复杂度: \(O(1)\)
最后
如果对你有帮助的话,请给我点个赞吧~
欢迎前往 我的博客 或 Algorithm - Github 查看更多题解