用特定分布的非均匀屏幕点填充向量

我正在尝试用非均匀屏幕点的特定分布填充向量。这些点代表屏幕上的某个 x 和 y 位置。在某个时候,我将在屏幕上绘制所有这些点,它们应该不均匀地分布在中心。基本上,点的频率应该随着您靠近中心而增加,其中屏幕的一侧是另一侧的反射(可以“镜像屏幕中心”)

我正在考虑使用某种公式(例如 -pi/2 和 pi/2 之间的 y=cos(x)),其中结果 y 将等于屏幕该区域中点的频率(其中 -pi /2 将是屏幕的最左侧,反之亦然),但我在创建点以放置在矢量上时我什至无法应用这样的东西。注意:必须生成特定数量的点

如果上述假设不起作用,那么实现这一点的一种欺骗方式可能是不断减少每个点之间的一些步长,但我不知道如何确保特定数量的点到达中心。

例如

python setup.py

从字面上看,任何帮助都将不胜感激。我简要地研究了 std::normal_distribution,但在我看来它依赖于随机性,所以我不确定这是否是我想要做的事情的好选择。

firefox_2009 回答:用特定分布的非均匀屏幕点填充向量

您可以使用称为拒绝抽样的方法。这个想法是你有一些参数的函数(在你的例子中是 2 个参数 x,y),它代表概率密度函数。在您的 2D 案例中,您可以生成一个 x,y 对以及一个表示概率 p 的变量。如果坐标处的概率密度函数较大(即 f(x,y) > p),则添加样本,否则生成新对。你可以这样实现:

#include <functional>
#include <vector>
#include <utility>
#include <random>

std::vector<std::pair<double,double>> getDist(int num){

    std::random_device rd{};
    std::mt19937 gen{rd()};

    auto pdf = [] (double x,double y) {
        return /* Some probability density function */;
    };

    std::vector<std::pair<double,double>> ret;
    
    double x,y,p;

    while(ret.size() <= num){
        x = (double)gen()/SOME_CONST_FOR_X;
        y = (double)gen()/SOME_CONST_FOR_Y;
        p = (double)gen()/SOME_CONST_FOR_P;

        if(pdf(x,y) > p) ret.push_back({x,y});
    }
    return ret;
}

这是一个非常粗略的草案,但应该给出它如何运作的想法。

另一个选项(如果您想要正态分布)是 std::normal_distribution。参考页面中的示例可以修改为:

#include <random>
#include <vector>
#include <utility>

std::vector<std::pair<double,double>> getDist(int num){

    std::random_device rd{};
    std::mt19937 gen{rd()};

    std::normal_distribution<> d_x{x_center,x_std};
    std::normal_distribution<> d_y{y_center,y_std};
 
    while(ret.size() <= num){
        ret.push_back({d_x(gen),d_y(gen)});
    }

}
,

有多种方法可以解决此问题,具体取决于您想要的确切分布。一般而言,如果您有一个分布函数 f(x),它可以为您提供到中心特定距离处的点的概率,那么您可以对其进行积分以获得 cumulative distribution function F(x)。如果 CDF 可以反转,则可以使用 inverse CDF 将均匀随机变量映射到距中心的距离,从而获得所需的分布。但并非所有功能都可以轻松反转。

另一种选择是稍微伪造一下:例如,制作一个循环,从 0 到距中心的最大距离,然后对于每个距离,您使用概率函数来获得预期的点数那个距离。然后只需以随机选择的角度添加那么多点。这非常快,结果可能已经足够好了。

Lala5th 提到的拒绝采样是另一种选择,它为您提供所需的分布,但如果屏幕的大面积区域的概率非常低,则可能需要很长时间。确保它在有限时间内完成的一种方法是在添加 num 点之前不循环,而是循环遍历每个像素,并在 pdf(x,y) > p 时添加该像素的坐标。这样做的缺点是您不会得到准确的 num 分。

本文链接:https://www.f2er.com/4328.html

大家都在问