搜索连续最小值时避免频繁推送/弹出的数据结构
Posted
技术标签:
【中文标题】搜索连续最小值时避免频繁推送/弹出的数据结构【英文标题】:Data structure for avoiding frequent pushing/popping when searching for successive minima 【发布时间】:2021-11-10 18:44:33 【问题描述】:我正在寻找一个 online algorithm 来处理我无法合理存储的更多数据。
我只想保留数据点n
,其中v[n]
的值小于以后的任何值。 (数值一般都在增加。)
执行此操作的明显方法(不是说唯一方法或正确方法)是使用堆栈。对于每一个新点,当它们的值大于当前点的值时,从堆栈中弹出点,然后将当前点压入堆栈。
但是数据非常稀疏。在快速测试中,每 TB 仅节省了大约 3 MB。
【问题讨论】:
我不太清楚你在问什么。如果要在连续接收值的同时保留最小的k
值,则应使用优先级队列,而不是堆栈。优先级队列通常实现为堆。要保留最小的 k
值,请使用最大堆。
@Stef 考虑 1、10、2、20、30、7、100。您保留 1、2、7 和 100,因为它们后面都没有更小的数字。如果您在内存中拥有所有数字,您只需向后遍历列表并连续输出较小的数字。但是因为这个列表是 TB 或 PB 长,所以这是不可行的。
恕我直言,问题不明确:在第一行中,您说,“...用于处理比我合理存储更多的数据”;但是在最后一个中,您说,“......每 TB 仅节省了大约 3 MB”。 3 MB 可以轻松存储,不是吗?
@Someone 困难在于通过的数据的TB / EB,而不是保存的微小数量。只是寻找一种可以很好地处理通过它的大量数据的良好结构(或算法)。
@Charles,我认为在处理(即“通过的数据的 TB/EB”)方面,您不能比 O(n)
做得更好,因为您需要检查整个输入数据。
【参考方案1】:
您可以分块处理数据。定义一个块的大小,以保证预期的结果大小适合它。所以如果我们说一千万个值被认为是一个块,那么我们也说最小值的数量永远不会超过一千万。然后进行如下操作:
预留一个数组来存储 1000 万个值 只要还有更多数据,继续重复以下步骤 用输入值填充数组的空闲部分 向后遍历整个数组以找到最小值。正如您所指出的,这可以在没有堆栈的情况下完成。它可以在数组中就地完成,方法是将找到的最小值保存在数组的右侧。 将这些最小值移动到数组的开始,在数组的右侧留下一个空闲部分,可以在下一次迭代中使用新的输入值填充。最后,您将在数组的开头找到最小值。
这可以通过在到达包含先前迭代结果的数组部分时停止向后迭代来优化,并且要与之比较的值也来自该部分。然后应该将数组右侧的部分移动到数组中的该点之后。
此算法可能比您的堆栈版本运行得更快,假设读取数组中的一大块输入数据可以非常快速地完成,并且将数组的一部分向左移动也可以快速完成(memcopy 类型的操作)。
【讨论】:
以上是关于搜索连续最小值时避免频繁推送/弹出的数据结构的主要内容,如果未能解决你的问题,请参考以下文章