提问人:MP3D 提问时间:3/1/2023 最后编辑:MP3D 更新时间:3/7/2023 访问量:159
c++ 圆圈中的随机点 - 我哪里出错了?
c++ random point in circle - where did I go wrong?
问:
class Solution {
private:
double c_radius;
double xcenter;
double ycenter;
public:
Solution(double radius, double x_center, double y_center) {
c_radius = radius;
xcenter = x_center;
ycenter = y_center;
}
vector<double> randPoint() {
double randomradius= (sqrt((double)rand()) / RAND_MAX) * c_radius;
double randomangle= ((double)rand() / RAND_MAX) * 360.0;
double yp= sin(randomangle)*randomradius;
double xp= cos(randomangle)*randomradius;
std::vector<double> point= {xp+xcenter, yp+ycenter};
return point;
}
};
大家好,我正在做一个关于在圆圈内找到一个随机点的 Leet Code 问题。一切顺利,直到以下测试:输入:[[0.01,-73839.1,-3289891.3]
它本质上是在圆圈内生成一个随机点,但是我的结果似乎是四舍五入的,我不确定为什么。
生成点后的输出:
[null,[-73839.10**000**,-3289891.30**000**],[-73839.10**000**,-3289891.30000],[-73839.10000,-3289891.30000],[-73839.10000,-3289891.30000],[-73839.10000,-3289891.30000]...
预期输出
[null,[-73839.10**006**,-3289891.30**228**],[-73839.10**541**,-3289891.30660],[-73839.10634,-3289891.30124],[-73839.10256,-3289891.30684],[-73839.09825,-3289891.29962]...
现在我的问题是错误在哪里?我的数学有问题吗?结果很接近,但还不够接近。我似乎无法确定此错误发生的位置。任何帮助都非常感谢。
答:
0赞
Marek R
3/1/2023
#1
使用您目前的方法,您将无法获得均匀分布(即使弧度是固定的)。 点将集中在一个中心。
任务描述说点分布应该是均匀的,但我怀疑是否编写了适当的统计测试。
相反,使这变得复杂,只需在包含圆的正方形中随机选择坐标,然后继续生成该点,直到它适合圆。
class Solution {
std::mt19937 gen;
std::uniform_real_distribution<> dis;
double xc;
double yc;
double r2;
public:
Solution(double radius, double x_center, double y_center)
: dis{-radius, radius}
, xc{x_center}
, yc{y_center}
, r2{radius * radius}
{
}
std::vector<double> randPoint() {
double dx, dy;
do {
dx = dis(gen);
dy = dis(gen);
} while (dx*dx + dy*dy > r2);
return {xc + dx, yc + dy};
}
};
评论
0赞
MP3D
3/1/2023
考虑到该函数最多会被调用 3 * 10^4 次,这不是非常低效吗?
0赞
Marek R
3/1/2023
恰恰相反。与圆形相比,被拒绝的区域非常小。这个区域的78%是一个圆。 并且比重试慢得多,检查点在一个圆圈内。sin
cos
sqrt
0赞
MP3D
3/1/2023
很酷,学到了一些东西!但是,我真的不确定 std::mt19937 gen;std::uniform_real_distribution<> 以及如何使用它们。谢谢你的回答。
0赞
Marek R
3/1/2023
用性能来证明这一点:quick-bench.com/q/4YLsNRGjt5kd-IfRtizk99Cf0u4
0赞
MP3D
3/1/2023
#2
似乎我在错误的地方进行了手术。使用后我计算了通过测试的结果。(感谢 chrysante)
完整代码:sqrt()
sqrt()
rand()/RAND_MAX
class Solution {
private:
double c_radius;
double xcenter;
double ycenter;
public:
Solution(double radius, double x_center, double y_center) {
c_radius = radius;
xcenter = x_center;
ycenter = y_center;
}
vector<double> randPoint() {
double randomradius= sqrt(((double)rand() / RAND_MAX)) * c_radius;
double randomangle= ((double)rand() / RAND_MAX) * 360.0;
double yp= sin(randomangle)*randomradius;
double xp= cos(randomangle)*randomradius;
return {xp+xcenter, yp+ycenter};
}
};
此代码通过了所有 Leetcode 测试。平方生根的结果是必要的,否则会抛出与原始帖子相同的错误。rand()/RAND_MAX
评论
0赞
Marek R
3/1/2023
您已经复制了 360 错误,请参阅“问题”下的评论。
评论
std::vector
point
vector2
std::pair<double, double>
std::tuple<double, double>
<random>
rand()