用于避免在搜索连续最小值时频繁推送/弹出的数据结构

Data structure for avoiding frequent pushing/popping when searching for successive minima

提问人:Charles 提问时间:9/16/2021 更新时间:9/16/2021 访问量:56

问:

我正在寻找一种在线算法来处理比我合理存储的更多的数据。

我只想保留值小于任何后续值的数据点。(这些值通常会增加。nv[n]

这样做的明显方法(不是说唯一的方法或正确的方法)是使用堆栈。对于每个新点,当其值大于当前点的值时,将点从堆栈中弹出,然后将当前点推到堆栈上。

但数据非常稀疏。在快速测试中,每 TB 仅节省约 3 MB。

优化 数据结构 语言不可知 在线算法

评论

0赞 Stef 9/16/2021
我不完全清楚你在问什么。如果要在连续接收值的同时保留最小值,则应使用优先级队列,而不是堆栈。优先级队列通常以堆的形式实现。若要保留最小值,请使用 max-heap。kk
0赞 Charles 9/16/2021
@Stef考虑 1、10、2、20、30、7、100。您保留 1、2、7 和 100,因为它们后面没有一个较小的数字。如果你把所有的数字都放在内存中,你只需向后浏览列表,然后连续输出较小的数字。但是,由于列表的长度为 TB 或 PB,因此不可行。
0赞 Someone 9/16/2021
恕我直言,问题尚不清楚:在第一行,你说,“......处理超出我合理存储能力的数据“;但在最后一个中,你说,“......每 TB 仅节省约 3 MB”。3 MB 可以轻松存储,不是吗?
0赞 Charles 9/16/2021
@Someone 困难在于通过的数据量为 TB/EB,而不是保存的少量数据。只是寻找一个好的结构(或算法)来使用,可以很好地处理这么多数据。
0赞 Someone 9/16/2021
@Charles,我认为你不能比处理(即“TB/EB的数据通过”)做得更好,因为你需要检查整个输入数据。O(n)

答:

1赞 trincot 9/16/2021 #1

您可以分块处理数据。定义块的大小,以便保证预期的结果大小适合它。因此,如果我们说 1000 万个值被认为是一个块,那么我们也说最小值的数量永远不会超过 1000 万。然后按以下步骤操作:

  • 保留一个用于存储 1000 万个值的数组
  • 只要有更多数据,请继续重复以下步骤
  • 用输入值填充数组的空闲部分
  • 向后浏览整个数组以找到最小值。正如你所指出的,这可以在没有堆栈的情况下完成。它可以在数组中就地完成,方法是将找到的最小值保存在数组的右侧。
  • 将这些最小值移动到数组的开头,在数组的右侧留下一个自由部分,可以在下一次迭代中使用新的输入值填充该部分。

最后,您将在数组的开头获得最小值。

这可以通过在到达包含上一次迭代结果的数组部分时停止向后迭代来优化,并且要比较的值也来自该部分。然后,数组右侧的部分应在数组中的此点之后移动。

假设读取数组中的输入数据块可以非常快,并且将数组的一部分向左移动也可以非常快(memcopy 类型的操作),则此算法的运行速度可能比堆栈版本更快。