为了供将来参考,我将列出我所知道的所有可以在滚动集合中维护的统计信息,每次重新计算为O(1)操作添加/删除(这实际上我应该从一开始就提出问题):
好的,所以更准确地说:这些不是我所知道的统计数据的“全部”。他们就是我现在能记住的那些人。
*可以在O(1)中重新计算仅用于添加,或者如果对集合进行排序,则可以重新计算添加和删除(但在这种情况下,插入不是O(1))。删除可能会导致对非排序集合进行O(n)重新计算。
**仅在O(1)中重新计算已排序的索引集合。
***需要相当复杂的数据结构才能在O(1)中重新计算。
****当权重以线性递减的方式分配时,当然可以在O(1)中实现加法和删除。在其他情况下,我不确定。
假设我保留了一组数字数据 - 比方说,只是一堆数字。对于这些数据,可能存在一些可能感兴趣的计算值;一个例子是总和。为了得到所有这些数据的总和,我可以......
选项1:遍历集合,添加所有值:
double sum = 0.0;
for (int i = 0; i < values.Count; i++) sum += values[i];
选项2:维护总和,无需迭代集合只是为了找到总和:
void Add(double value) {
values.Add(value);
sum += value;
}
void Remove(double value) {
values.Remove(value);
sum -= value;
}
编辑:为了将这个问题放在更相关的术语中,让我们将上面的两个选项与(某种)现实世界的情况进行比较:
假设我开始大声列出数字并要求你把它们放在头脑中。我先说“11,16,13,12”。如果你只是记住这些数字本身而已,而且我说,“总和是多少?”,你必须自己想一想,“好吧,11 + 16 + 13 + 12是什么?”在回答之前,“52。”另一方面,如果你在列出数字时自己跟踪总和(即,当我说“11”时你认为“11”,当我说“16”时“,你想,”27,“等等,你可以马上回答”52“。然后,如果我说“好的,现在忘记16号”,如果你一直在跟踪你的头脑中的总和,你可以简单地从52离开,并知道新的总和是36,而不是16关列表和他们总结了11 + 13 + 12。
所以我的问题是,除了总和和平均等明显的计算之外,还有哪些其他计算是这样的?
第二次编辑:作为统计数据的一个任意例子(我几乎可以肯定) 需要迭代 - 因此无法简单地维护或者平均 - 考虑一下我是否问你,“这个系列中有多少数字可以被min整除?”假设数字是5,15,19,20,21,25和30.该组的最小值为5,分为5,15,20,25和30(但不是19或21),所以答案是5.现在,如果我从集合中删除5并提出相同的问题,答案现在是2,因为只有15和30可以被新的15分组整除;但是,就我所知,如果不再通过该集合,你就无法知道。
所以我认为这是我的问题的核心:如果我们可以将种的统计数据划分为这些类别,那些可维护(我自己的术语,也许那些需要迭代来计算任何时候集合被改变的,那些可维护的是什么?
我所询问的与online algorithm并不完全相同(尽管我真诚地感谢那些向我介绍过这个概念的人)。在线算法可以开始工作,甚至没有看到所有输入数据;我正在寻找的可维护的统计数据肯定会看到所有数据,只要它发生变化,它们就不需要一遍又一遍地重复。
答案 0 :(得分:14)
首先,您想要的术语是online algorithm。所有moments(平均值,标准偏差,偏斜等)都可以在线计算。其他包括最小值和最大值。请注意,无法在线计算中位数和mode。
答案 1 :(得分:3)
要始终保持高/低,您可以按排序顺序存储数据。有一些用于维护数据结构的算法可以保留排序。
如果数据是有序的,则中位数是微不足道的。
如果数据略微减少到频率表,则可以保持模式。如果将数据保存为随机,平坦的值列表,则无法在存在更改的情况下轻松计算模式。
答案 2 :(得分:2)
在线算法的this question答案可能很有用。关于满足您需求的可用性,我想说虽然一些在线算法可用于估计带有部分数据的汇总统计数据,但其他算法可用于根据您的需要从数据流中维护它们。
您可能还想查看复杂事件处理(或CEP),它用于跟踪和分析实时数据,例如在金融或网络商务中。我所知道的唯一免费CEP产品是Esper。
答案 3 :(得分:1)
作为Jason says,您确实在描述在线算法。我也看到过这种类型的计算,称为Accumulator Pattern,无论是显式实现还是通过递归实现。
答案 4 :(得分:1)
并非真正直接回答您的问题,但对于许多非在线统计数据的统计数据,您通常可以找到一些规则,只能通过迭代计算部分时间,并在其余时间缓存正确的值。这对你来说可能够好吗?
对于高价值,例如:
public void Add(double value) {
values.Add(value);
if (value > highValue)
highValue = value;
}
public void Remove(double value) {
values.Remove(value);
if (value.WithinTolerance(highValue))
highValue = RecalculateHighValueByIteration();
}
答案 5 :(得分:1)
使用恒定时间添加和删除操作不可能保持高或低,因为这会为您提供线性时间排序算法。您可以使用搜索树按排序顺序维护数据,从而为您提供最小和最大的对数时间。如果你还保留子树大小和计数,那么找到中位数也很简单。
如果您只想在存在添加和删除的情况下保持高或低,请查看优先级队列,这些队列比搜索树更有效。
答案 6 :(得分:0)
如果您事先不知道数据集的确切大小,或者它是否可能未被提及,或者您只是想要一些想法,那么您一定要研究Streaming Algorithms中使用的技术。
答案 7 :(得分:0)
您正在描述在线算法(甚至在您的第二次编辑之后),并且还要求您允许“删除”操作。一个例子是用于finding frequent items in a stream的“草图算法”。