首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何计算排序时的“进度”?

如何计算排序时的“进度”?
EN

Stack Overflow用户
提问于 2012-12-16 12:42:41
回答 5查看 1.2K关注 0票数 10

我使用stable_sort对一个大的vector进行排序。

排序需要几秒钟(比方说,5-10秒),我想向用户显示一个进度条,显示到目前为止完成了多少排序。

但是(即使我要写自己的排序例程)我怎么知道我已经取得了多大的进步,还有多少工作要做呢?

我不需要它准确,但我需要它是“合理的”(即合理的线性,不是伪造的,当然也不是回溯)。

EN

回答 5

Stack Overflow用户

发布于 2012-12-16 13:07:19

将向量分成几个相等的部分,数量取决于您所需的进度报告粒度。分别对每个部分进行排序。然后开始与std::merge合并。您可以在对每个部分进行排序和每次合并后报告进度。您需要进行实验,以确定与合并相比,对部分的排序应该计算多少百分比。

编辑:

我自己做了一些实验,发现与排序相比,合并是微不足道的,这是我想出的函数:

代码语言:javascript
复制
template<typename It, typename Comp, typename Reporter>
void ReportSort(It ibegin, It iend, Comp cmp, Reporter report, double range_low=0.0, double range_high=1.0)
{
    double range_span = range_high - range_low;
    double range_mid = range_low + range_span/2.0;
    using namespace std;
    auto size = iend - ibegin;
    if (size < 32768) {
       stable_sort(ibegin,iend,cmp);        
    } else {
        ReportSort(ibegin,ibegin+size/2,cmp,report,range_low,range_mid);
        report(range_mid);
        ReportSort(ibegin+size/2,iend,cmp,report,range_mid,range_high);
        inplace_merge(ibegin, ibegin + size/2, iend);
    }   
}

int main()
{
    std::vector<int> v(100000000);
    std::iota(v.begin(), v.end(), 0);
    std::random_shuffle(v.begin(), v.end());

    std::cout << "starting...\n";

    double percent_done = 0.0;
    auto report = [&](double d) {
        if (d - percent_done >= 0.05) {
            percent_done += 0.05;
            std::cout << static_cast<int>(percent_done * 100) << "%\n";
        }
    };
    ReportSort(v.begin(), v.end(), std::less<int>(), report);
}
票数 1
EN

Stack Overflow用户

发布于 2012-12-16 12:59:56

稳定排序是基于合并排序的。如果您编写了自己版本的合并排序(忽略一些加速技巧),您将看到它由log N遍组成。每次遍历从2^k个排序列表开始,并生成2^(k-1)个列表,在将两个列表合并为一个列表时完成排序。因此,您可以使用k的值作为进度的指示。

如果您要运行实验,您可能会检测比较对象以计算进行的比较的数量,并尝试查看进行的比较的数量是否为n log n的某个合理的可预测倍数。然后,您可以通过计算完成的比较的数量来跟踪进度。

(请注意,对于C++稳定排序,您必须希望它找到足够的存储来保存数据的副本。否则,成本从N log N到N (log N)^2,您的预测将过于乐观)。

票数 0
EN

Stack Overflow用户

发布于 2012-12-16 13:11:08

选择一小部分索引并计算反转次数。你知道它的最大值,并且你知道当你完成时,它的值是零。所以,你可以使用这个值作为“进度条”。你可以把它看作是熵的一种度量。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13898675

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档