我试图了解here和this presentation的第35页
中描述的simimiled cache notivious lookahead array插入简化分析 分形树:
- 合并的成本2个大小为X的数组是O(X = B)块I / O.合并是非常的 I / O效率很高。
- 要合并的每个元素的成本是O(1 / B),因为O(X)元素是 合并。
- 每个元素合并的最大次数是O(logN)。
- 平均插入成本为O(logN / B)
醇>
我可以看到#1,#2和#3,但我无法理解#4,从论文中,合并可以被视为二进制加法进位,例如,(31)B可以呈现:
11111个
当插入一个新项目(加1)时,应该有5 = log(32)合并(5个携带)。但是,在这种情况下,我们必须合并32个元素!另外,如果每次我们加1,那么将从0到2 ^ k执行多少次携带? anwser应为2 ^ k - 1.换句话说,每次插入一次合并!
那么如何计算#4?
答案 0 :(得分:6)
虽然你在两者上都是正确的,但在最坏情况下合并元素(以及传输)的数量是N,并且合并的总数也是相同的顺序,平均插入成本仍然是对数的。它来自两个事实:合并成本不同,低成本合并的数量远远高于高成本合并的数量。
通过示例可能更容易看到 设置B = 1(即每个块1个元素,每个合并的最坏情况都有成本)和N = 32(例如我们将32个元素插入到最初为空的数组中)。 一半的插入(16)将一个元素放入大小为1的空子阵列中,因此不会导致合并。在剩余的插入中,一个(最后一个)需要合并(移动)32个元素,一个(第16个)移动16,两个(第8个和第24个)移动8个元素,四个移动4个元素,以及8个移动2个元素。因此,元素移动的总数为96,给出每次插入3次移动的平均值。
希望有所帮助。
答案 1 :(得分:5)
第一个日志B级别适合(单页)内存,因此在这些级别中发生的任何内容都不会产生I / O. (这也解决了rrenaud分析每个插入时有O(1)合并的问题,因为你只在第一个log B合并后才开始为它们付费。)
一旦你合并了至少B个元素,那么事实2就会开始。
从元素的角度考虑工作。它合并为O(log N)次。每次发生时都会收取O(1 / B)的费用。它的总插入成本是O((log N)/ B)(需要额外的parens来区分O(log N / B),这将是非常糟糕的插入性能 - 甚至比B树更差)。 / p>
“平均”成本实际上是摊销成本 - 它是您为其插入而向该元素收取的金额。更正式地说,它是插入N个元素的总工作量,然后除以N. O((log N)/ B)的摊销成本实际上意味着插入N个元素是O((N log N)/ B)I / Os - 整个序列。这与B树相比非常有利,对于N次插入,B树总共执行O((N log N)/ log B)I / O.除以B显然比除以log B要好得多。
你可能会抱怨工作是块状的,你有时会插入导致大量的合并。没关系。您不会将所有合并收费到最后一次插入。每个人都为他们参与的每次合并支付了自己的少量金额。由于(log N)/ B通常远小于1,因此在所有合并过程中,每个人的收费方式都少于一个I / O.参加。
如果您不喜欢摊销分析会发生什么,并且您说即使插入吞吐量上升了几个数量级,当单个插入可能导致大量工作时您也不喜欢它?啊哈!有一些标准的方法来解密这样的数据结构,在每次插入过程中你都会进行一些抢先合并。你得到了相同的I / O复杂性(你必须接受我的意见),但对于那些关心摊销分析和解除结果的人来说,这是非常标准的东西。
完全披露:我是COLA论文的作者之一。此外,rrenaud在我的算法课上。另外,我是Tokutek的创始人。
答案 2 :(得分:0)
通常,每个增量的已分配的已更改位数为2 = O(1)。
这是逻辑/推理的证明。 http://www.cs.princeton.edu/courses/archive/spr11/cos423/Lectures/Binary%20Counting.pdf
这是通过实验的“证明”。 http://codepad.org/0gWKC3rW