0
点赞
收藏
分享

微信扫一扫

正则采样 自适应方法 并行正则采样排序

phpworkerman 2022-04-25 阅读 72

前言

正则采样,就是从原数组中尽量等间隔的取出采样点。

最近在学习MPI并行编程,今天手撕并行正则采样排序时遇到一个难题——如何实现正则采样? 这部分在CSDN上没人介绍,我自己琢磨了一种自适应的方法。其效果还没有进行大量测试,下面说一下我的思路。

代码

先贴出代码,后续讨论

void regular_samp(int* raw, int count, int* samp, int k)
{
    int step = floor((count - k) / (k + 1));
    int j = 0, left = count;
    for (int i = step - 1; i < count && j < k; i += step)
    {
        samp[j++] = raw[i];
        left -= step;
        step = round(double(left - (k - j)) / (k - j + 1)) + 1;
    }
}

最初想法

上述代码实现的是从包含count个元素的raw数组中正则采样k个元素到samp数组中。

所谓正则采样,最理想的情况就是等间隔采样。

比如从 1 2 3 4 5 6 7中取3个数——2 4 6。间隔为2(两个采样数字之间的距离)

因此我最初的想法就是计算间隔(step)等于多少,从count个数中取出k个数,然后均分成k + 1段。如果下标从0开始计算,也就是说认为还有两个隐含的采样点 -1 和 count。

提出公式: s t e p = c o u n t − k k + 1 + 1 step= \frac{count - k}{k + 1} + 1 step=k+1countk+1

但很多时候分数并不整除,这时候问题来了,对于分式的结果我们向上取整还是向下取整还是四舍五入?

按我的测试,这些方案都不合适。

比如 1 2 3 4 5取3个数,最理想的结果应该是1 3 5。如果向上取整,step = 2,干脆取不到三个数。如果向下取整,step = 1,取得的是1 2 3,很不合理。

自适应方法

基本思路还是按照step的大小决定数在哪里取得。但自适应方法,就是让算法依据子问题自动决定step的大小。每次取出一个数,直到取出所有数。

原问题是从包含count个元素的raw数组中正则采样k个元素到samp数组中。取出一个数后,问题变成从count - step个数中正则采样k - 1个数。

第一个step计算我使用了向下取整方式,因为-1那个默认的采样点是不存在的,这里的间隔可以损失一些。后面则采用四舍五入方法。

结语

按照我在并行正则采样排序中的实践,效果还是不错的。欢迎大家指出问题。

举报

相关推荐

0 条评论