当前位置:网站首页>【Leetcode】478. Generate Random Point in a Circle(配数学证明)
【Leetcode】478. Generate Random Point in a Circle(配数学证明)
2022-08-01 23:47:00 【记录算法题解】
题目地址:
https://leetcode.com/problems/generate-random-point-in-a-circle/
给定二维圆的圆心坐标 ( x 0 , y 0 ) (x_0,y_0) (x0,y0)及其半径 r r r,要求等概率产生在圆内的点的坐标。圆周上的点也视为有效。
法1:拒绝采样法。只需要能等概率产生单位圆中的随机点即可,可以用拒绝采样法。产生 [ − 1 , 1 ] 2 [-1,1]^2 [−1,1]2中的随机点是简单的,每次产生了 ( x , y ) (x,y) (x,y)之后,只当 x 2 + y 2 ≤ 1 x^2+y^2\le 1 x2+y2≤1的时候才停止采样,那么由于每次采样在范围内的概率 π 4 < 1 \frac{\pi}{4}<1 4π<1,采样次数服从几何分布,所以采样以概率 1 1 1停止,设采样停止这个事件为 A A A,设圆内有个小面积 S S S,则 P ( ( x , y ) ∈ S ∣ A ) = P ( ( x , y ) ∈ S ) P((x,y)\in S|A)=P((x,y)\in S) P((x,y)∈S∣A)=P((x,y)∈S)即为 S S S的面积,从而满足题意。采样次数的期望为 4 π \frac{4}{\pi} π4。代码如下:
import java.util.Random;
public class Solution {
Random random;
double xc, yc, r, x, y;
public Solution(double radius, double x_center, double y_center) {
random = new Random();
xc = x_center;
yc = y_center;
r = radius;
}
public double[] randPoint() {
do {
generate();
} while (!check(x, y));
return new double[]{
xc + r * x, yc + r * y};
}
void generate() {
x = random.nextDouble() * 2 - 1;
y = random.nextDouble() * 2 - 1;
}
boolean check(double x, double y) {
return x * x + y * y <= 1.0;
}
}
randPoint时空复杂度 O ( 1 ) O(1) O(1)。
法2:设 ( R , Θ ) (R, \Theta) (R,Θ)满足 [ 0 , 1 ] × [ 0 , 2 π ] [0, 1]\times [0,2\pi] [0,1]×[0,2π]的均匀分布,则 ( X , Y ) = ( R cos Θ , R sin Θ ) (X,Y)=(\sqrt R\cos\Theta, \sqrt R\sin\Theta) (X,Y)=(RcosΘ,RsinΘ)满足单位圆的均匀分布。
证明:设 ( x ( r , θ ) , y ( r , θ ) ) = ( r cos θ , r sin θ ) (x(r,\theta), y(r,\theta))=(\sqrt r\cos\theta, \sqrt r\sin\theta) (x(r,θ),y(r,θ))=(rcosθ,rsinθ),设 ( X , Y ) (X,Y) (X,Y)的密度函数为 p ( x , y ) p(x,y) p(x,y),那么面积微元 p ( x , y ) d x d y = p ( r cos θ , r sin θ ) ∣ J ∣ d r d θ = 1 2 π d r d θ p(x, y)dxdy=p(r\cos\theta, r\sin\theta)|J|drd\theta=\frac{1}{2\pi}drd\theta p(x,y)dxdy=p(rcosθ,rsinθ)∣J∣drdθ=2π1drdθ其中 J J J是Jacobi矩阵, J = [ ∂ x ∂ r ∂ x ∂ θ ∂ y ∂ r ∂ y ∂ θ ] = [ cos θ 2 r − r sin θ sin θ 2 r r cos θ ] J = \begin{bmatrix} \dfrac{\partial x}{\partial r} & \dfrac{\partial x}{\partial \theta}\\ \dfrac{\partial y}{\partial r} & \dfrac{\partial y}{\partial \theta}\end{bmatrix}= \begin{bmatrix} \dfrac{\cos\theta}{2\sqrt r} & -\sqrt r\sin\theta\\ \dfrac{\sin\theta}{2\sqrt r} & \sqrt r\cos\theta \end{bmatrix} J=⎣⎡∂r∂x∂r∂y∂θ∂x∂θ∂y⎦⎤=⎣⎡2rcosθ2rsinθ−rsinθrcosθ⎦⎤ ∣ J ∣ = 1 2 |J|=\frac{1}{2} ∣J∣=21,从而 p ( x , y ) = 1 π p(x,y)=\frac{1}{\pi} p(x,y)=π1,满足题意。代码如下:
import java.util.Random;
public class Solution {
Random random;
double r, x, y;
public Solution(double radius, double x_center, double y_center) {
random = new Random();
this.r = radius;
this.x = x_center;
this.y = y_center;
}
public double[] randPoint() {
double theta = random.nextDouble() * 2 * Math.PI;
double randomR = r * Math.sqrt(random.nextDouble());
return new double[]{
x + randomR * Math.cos(theta), y + randomR * Math.sin(theta)};
}
}
randPoint时空复杂度 O ( 1 ) O(1) O(1)。
法1:C++:
class Solution {
public:
double r, xc, yc, x, y;
Solution(double radius, double x_center, double y_center) {
r = radius;
xc = x_center;
yc = y_center;
}
vector<double> randPoint() {
double x, y;
do {
x = (double)rand() / RAND_MAX * 2 - 1;
y = (double)rand() / RAND_MAX * 2 - 1;
} while (x * x + y * y > 1);
return {
xc + x * r, yc + y * r};
}
};
时空复杂度一样。
法2:C++(C++里的 π \pi π可以由 arccos − 1 \arccos-1 arccos−1得到):
class Solution {
public:
double r, xc, yc, x, y;
Solution(double radius, double x_center, double y_center) {
r = radius;
xc = x_center;
yc = y_center;
}
vector<double> randPoint() {
double radius = sqrt((double)rand() / RAND_MAX) * r;
double theta = ((double)rand() / RAND_MAX) * 2 * acos(-1);
return {
xc + radius * cos(theta), yc + radius * sin(theta)};
}
};
时空复杂度一样。
边栏推荐
- Flink Yarn Per Job - Yarn应用
- 问题解决方式了
- Flink学习第三天——一文带你了解什么是Flink流?
- numpy.around
- Calculate the angle of a line defined by two points
- Deep Learning Fundamentals - Numpy-based Recurrent Neural Network (RNN) implementation and backpropagation training
- Dynamic Scene Deblurring with Parameter Selective Sharing and Nested Skip Connections
- 在CentOS下安装MySQL
- 如何用Redis实现分布式锁?
- YOLO等目标检测模型的非极大值抑制NMS和评价指标(Acc, Precision, Recall, AP, mAP, RoI)、YOLOv5中[email protected]与
猜你喜欢
检查 Oracle 版本的 7 种方法
Quartus uses tcl files to quickly configure pins
机器学习文本分类
2022还想上岸学习软件测试必看,测试老鸟的肺腑之言...
Spark Sql之join on and和where
cdh6 opens oozieWeb page, Oozie web console is disabled.
20220725资料更新
云原生DevOps环境搭建
Thesis understanding [RL - Exp Replay] - Experience Replay with Likelihood-free Importance Weights
Flink学习第三天——一文带你了解什么是Flink流?
随机推荐
color transparency parameter
尚硅谷MySQL学习笔记
What is CICD excuse me
sys_kill system call
ELK日志采集
UI自动化测试框架搭建-标记性能较差用例
Dynamic Scene Deblurring with Parameter Selective Sharing and Nested Skip Connections
Quartus uses tcl files to quickly configure pins
Secondary Vocational Network Security Competition B7 Competition Deployment Process
【MySQL系列】 MySQL表的增删改查(进阶)
Flink Yarn Per Job - CliFrontend
Data Organization --- Chapter 5 Trees and Binary Trees --- The Concept of Binary Trees --- Application Questions
What can be done to make this SQL into a dangerous SQL?
C language - branch statement and loop statement
架构基本概念和架构本质
Quartus 使用 tcl 文件快速配置管脚
CDH6 Hue to open a "ASCII" codec can 't encode characters
经典文献阅读之--DLO
chrome copies the base64 data of an image
cdh的hue上oozie启动报错,Cannot allocate containers as requested resource is greater than maximum allowed