增量中值计算,最大内​​存效率

时间:2010-07-30 13:40:53

标签: algorithm median

4 个答案:

答案 0 :(得分:10)

您将需要存储至少ceil(n / 2)点,因为前n / 2点中的任何一个可能是中位数。存储点并找到中位数可能是最简单的。如果保存ceil(n / 2)点是有价值的,那么在前n / 2点读入一个排序列表(二叉树可能是最好的),然后当添加新点时抛出低点或高点并保持追踪任意一端的点数。

修改

如果流长度未知,那么显然,正如斯蒂芬在评论中所观察到的那样,那么我们别无选择,只能记住一切。如果可能存在重复项目,我们可以使用Dolphins存储值和计数的想法来节省一些内存。

答案 1 :(得分:2)

你可以

  • 使用统计数据,如果可以接受 - 例如,您可以使用抽样。
  • 使用有关您的号码流的知识
    • 使用类似计数的方法:k不同的值意味着存储O(k)内存)
    • 或抛弃已知的异常值并保持(高,低)计数器。
    • 如果您知道没有重复项,则可以使用位图...但这只是O(n)的较小常量。

答案 2 :(得分:1)

如果您有离散值和大量重复,您可以存储值和计数,这将节省一些空间。

可能在计算阶段你可以丢弃顶部的'n'和底部'n'值,只要你确定中位数不在那个顶部或底部范围内。<登记/> 例如假设您期待100,000个值。每次存储的数量达到(例如)12,000时,您可以丢弃最高1000和最低1000,将存储量减少到10,000。

如果值的分布相当一致,这将很有效。但是,如果有可能在最后接收到大量非常高或非常低的值,则可能会使计算失真。基本上,如果您丢弃小于(最终)中位数的“高”值或等于或大于(最终)中位数的“低”值,则计算结束。

<强>更新
一点例子 假设数据集是数字1,2,3,4,5,6,7,8,9 通过检查,中位数为5。

假设您获得的前5个数字是1,3,5,7,9 为了节省空间,我们丢弃最高和最低,留下3,5,7
现在得到两个,2,6,所以我们的存储是2,3,5,6,7
丢弃最高和最低,留下3,5,6
得到最后两个4,8,我们有3,4,5,6,8
中位数仍然是5,世界是个好地方。

但是,我们可以说前五个数字是1,2,3,4,5 丢弃顶部和底部,留下2,3,4
得到两个6,7,我们有2,3,4,6,7
丢弃顶部和底部离开3,4,6
得到最后两个8,9,我们有3,4,6,8,9
中位数为6,这是不正确的。

如果我们的数字分布均匀,我们可以继续修剪四肢。如果他们可能聚集在一大堆或许多小数字中,那么丢弃是有风险的。

答案 3 :(得分:1)

我遇到了同样的问题,但有一种方法尚未在此处发布。希望我的回答将来能对某人有所帮助。

如果您知道您的值范围,并且不太在乎中间值的精度,则可以使用常量内存逐步创建量化值的直方图。这样很容易找到量化值的中位数或任何位置。

例如,假设您的数据流是图像像素值,并且您知道这些值是都在0〜255之间的整数。要逐步创建图像直方图,只需从零开始创建256个计数器(仓),然后在扫描输入时在与像素值相对应的仓中计数1。创建直方图后,找到大于数据大小一半的第一个累积计数以获取中位数。

对于实数数据,您仍然可以计算直方图,每个bin具有量化的值(例如10、1或0.1的bin等),具体取决于期望的数据值范围和所需的精度。 / p>

如果您不知道整个数据样本的值范围,则仍可以估算中值的可能值范围,并计算该范围内的直方图。这会自然降低异常值,但正是我们在计算中位数时想要的。