如果我没有误解摊销分析,那么这个考试问题实在是偷偷摸摸。所以我想我是误会。
"实现一个容量为n的Set ADT,它可以包含小于或等于n的所有正整数。要求:
new Set(n) - O(n)
insert(i) - O(1)
成员(i) - O(1)
union(s) - O(1),其中s是相同类型的Set。如果你愿意,你可以销毁s。
对操作进行运行时分析。如果需要,可以使用摊销分析。"
您可以将其实现为大小为n的布尔数组。十分简单。唯一的难点是联合行动。我无法弄明白,解决方案建议使用for循环做大小的' AND操作,显然是O(n)。但是在for循环之后,他们将s的布尔数组设置为null,并声称这使得分摊的运行时间为O(1)!
当然,如果你继续将你的新组合用于同一组,n次,你的平均运行时间为O(1),因为只有一个操作是O(n),其余的是是不变的。但为什么我们会关心呢?你如何证明这种分析的合理性?如何在摊销分析的公平基准上进行无意义的操作?
答案 0 :(得分:0)
让我们暂时忽略insert(i)和member(i)查询,并专注于创建新集和形成联合。
诀窍在于,如果你在执行联合之后销毁s,那么在任何新的集合创建和联合操作的序列中,它永远不可能执行比集合创建更多的联合:每个联合操作需要至少有2套当前存在,并将存在的总数减少1。
考虑c新集合创建的任何序列,并且u< c联合运算:这将采用O(nc + nu + c + u)= O(nc + nu)时间。 (集合创建允许为O(n),这也是直接联合计算的时间。)事实我们知道你< c意味着我们可以设计一个新的成本系统,在这个系统中,对于任何这样的序列,我们可以将每个联合操作与先前发生的不同集合创建相匹配,并且收费联合到匹配集创建的时间。在这个新的成本系统中,所有联合操作都需要时间O(1),所有与稍后的联合操作匹配的设置创建需要时间O(n + 1)+ O(n + 1)= O(n),并且不匹配set creations需要时间O(n + 1)= O(n)和以前一样。请注意,虽然个别成本已经移动,但新系统下的总成本与原始成本相同:O(2nu + n(cu)+ c + u)= O(nc + nu) )。
因此,如果悲观地假设每个集合创建将被收取一些未来的联合操作,那么每个集合创建的成本变为(或者更确切地说,保持)O(n + 1)+ O (n + 1)= O(n),并且每个联合运算的成本变为O(1),这个更新的成本将是新成本系统的上限(即永远不会低估),这是真正的成本任何创作和联合作战序列。