当前位置:网站首页>【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)};
}
};
时空复杂度一样。
边栏推荐
- 中职网络安全竞赛B7比赛部署流程
- 在linux下MySQL的常用操作命令
- Special characters & escapes in bat
- Loading configuration of Nacos configuration center
- Enterprise firewall management, what firewall management tools are there?
- Check if point is inside rectangle
- Programmer is still short of objects? A new one is enough
- Get piggy homestay (short-term rental) data
- Flink学习第四天——完成第一个Flink 流批一体案例
- Artifact XXXwar exploded Artifact is being deployed, please wait...(已解决)
猜你喜欢

1个月写900多条用例,二线城市年薪33W+的测试经理能有多卷?

A brief analysis of mobile APP security testing in software testing, shared by a third-party software testing agency in Beijing

使用Jenkins做持续集成,这个知识点必须要掌握

thinkphp漏洞总结

Flink学习第三天——一文带你了解什么是Flink流?
![[LeetCode304周赛] 两道关于基环树的题 6134. 找到离给定两个节点最近的节点,6135. 图中的最长环](/img/63/16de443caf28644d79dc6e6889e5dd.png)
[LeetCode304周赛] 两道关于基环树的题 6134. 找到离给定两个节点最近的节点,6135. 图中的最长环

Various Joins of Sql

Data Organization --- Chapter 5 Trees and Binary Trees --- The Concept of Binary Trees --- Application Questions

sys_kill system call

TexturePacker使用文档
随机推荐
[C language advanced] file operation (2)
Getting started with IDEA is enough to read this article
【C语言进阶】文件操作(二)
Convert LocalDateTime to Date type
尚硅谷MySQL学习笔记
6132. 使数组中所有元素都等于零-快速排序法
【MySQL系列】MySQL索引事务
PostgreSQL Basics--Common Commands
chrome copies the base64 data of an image
Additional Features for Scripting
月薪12K,蝶变向新,勇往直前—她通过转行测试实现月薪翻倍~
WEB安全基础 - - - XRAY使用
【MySQL篇】初识数据库
Dynamic Scene Deblurring with Parameter Selective Sharing and Nested Skip Connections
6134. Find the closest node to the given two nodes - force double hundred code
如何用Redis实现分布式锁?
@Scheduled注解详解
6132. All the elements in the array is equal to zero - quick sort method
切面打印调取的方法
What is CICD excuse me