Performance 有限排序/过滤算法

Performance 有限排序/过滤算法,performance,algorithm,sorting,filter,Performance,Algorithm,Sorting,Filter,我有一个相当大的元素列表(1000个) 我有一个可以接受或不接受元素的过滤器 我想要满足过滤器要求的前100个元素 到目前为止,我已经对结果进行了排序,然后选择了满足筛选条件的前100名。这背后的基本原理是,过滤器并非完全快速 但是现在,排序步骤比过滤步骤要长,所以我想以某种方式将它们结合起来 是否有一种算法可以将排序/筛选的关注点结合起来,以获得满足筛选要求的前100个结果,而不会产生对所有元素进行排序的成本?我通过使用二叉树进行排序并在插入期间将元素计数保持在当前节点的左侧,解决了这个确切的

我有一个相当大的元素列表(1000个)

我有一个可以接受或不接受元素的过滤器

我想要满足过滤器要求的前100个元素

到目前为止,我已经对结果进行了排序,然后选择了满足筛选条件的前100名。这背后的基本原理是,过滤器并非完全快速

但是现在,排序步骤比过滤步骤要长,所以我想以某种方式将它们结合起来


是否有一种算法可以将排序/筛选的关注点结合起来,以获得满足筛选要求的前100个结果,而不会产生对所有元素进行排序的成本?

我通过使用二叉树进行排序并在插入期间将元素计数保持在当前节点的左侧,解决了这个确切的问题。有关详细信息,请参见(图4.4等)。

我的直觉是从列表中选择前100个元素(比排序便宜得多,请使用您最喜欢的QuickSelect变体)。通过过滤器运行这些操作,产生
n
成功和
100-n
失败。如果
n<100
,则从列表其余部分的顶部选择
100-n
元素,重复此操作:

k = 100
while (k > 0):
    select top k from list and remove them
    filter them, yielding n successes
    k = k - n
由于每个选择步骤都在这段时间内运行,因此这一过程的运行时间与列表的长度成正比,所需的选择步骤数量取决于过滤器的成功率,而不是直接取决于列表的大小

不过,我想这会有一些坏情况。如果几乎所有元素都未通过筛选,那么它比仅对所有内容进行排序要慢得多,因为您最终会选择数千次。因此,如果情况不好,您可能需要一些标准来帮助解决问题,然后返回到对整个列表进行排序

它还有一个问题,即它可能会在最后进行大量的小选择,因为如果过滤条件与排序条件无关,我们预计k将以指数形式衰减。因此,您可以通过在每个步骤中选择略多于k个元素来改进它。比方说,k除以过滤器的预期成功率,再加上一个小常数。如果没有可用于预测的领域知识,则基于过去性能的期望,以及通过实验选择的小常数,以避免查找最后几个元素的步骤过多。如果您在任何步骤结束时,通过筛选的项目数超过您仍在查找的项目数(即,n>k),则从当前成功批次中选择前k个,您就完成了


由于QuickSelect为您提供了前k个元素,而没有对这些k进行排序,因此如果您需要按顺序排列前100个元素,则需要对100个元素进行最后排序。

如果我理解正确,您有两种选择:

  • 选择100个元素-N个过滤器检查操作。然后100(lg 100)用于排序

  • 排序,然后选择100个元素-至少N(lg N)进行排序,然后选择


第一个听起来比排序短,然后选择。

我可能会先过滤,然后将结果插入优先级队列。跟踪PQ中的项目数,插入后,如果项目数大于您想要保留的项目数(在您的情况下为100),请弹出最小的项目并将其丢弃。

Steve建议使用快速排序

1读入前1000个左右的元素。
2对它们进行排序并选择第100个最大元素。
3以步骤2中的元素为轴心,对整个文件运行一次快速排序。
4选择快速排序过程结果的上半部分进行进一步处理


保证在单次快速排序的上半部分至少包含100个元素。假设前1000个元素合理地代表了整个文件,那么在第4步,您应该得到大约十分之一的原始元素。

如果不进行排序,您如何定义“top”?@dlev:您仍然需要排序。。。如果你知道你只需要几个“最高”值,你就不必对整个集合进行排序。+1这正是我要写的。完整性-预期运行时间为O(np+k log k)时间和O(np)过滤器应用程序,其中p是任何元素通过过滤器的概率。你不需要随着窗口的大小呈指数增长,顺便说一句-如果你假设元素以概率p独立通过过滤器,那么概率确实会呈指数下降。是的,我的噩梦场景“几乎所有元素都无法通过过滤器”只能在列表变长时才成立,如果过滤器不独立于元素的列表长度和排序顺序,但事实上在问题的更大版本中变得更挑剔。我认为,处理任何这种相互关系都超出了简单的复杂性分析的范围。因此,我很高兴你的独立性假设,并且假设它完全可以避免对那起致命案件的担忧。事实上,在你的评论中,
p
不是一个元素过滤失败的概率吗?也就是说,如果过滤器接受大多数内容,那么我们应该减少对过滤器的应用,而不是更多。我喜欢这个解决方案,尽管我同意你不应该在每一步都选择k,因为你得到99的噩梦在第一次点击时通过,而在下一次点击时通过,正好得分最差,你基本上有n^2个发生。我很可能会在固定大小的块中进行搜索,因为过滤器的成功概率在很大程度上取决于执行搜索的用户。此外,如果我们预期一定百分比的失败,那么将初始选择值设置为大于k可能是有意义的。我将对各种分块方法进行实验,并进行汇报。虽然过滤整个列表的时间要快一些,但实际的过滤行为有一个与之相关的不平凡的成本。在某个临界点,过滤f