在摊还分析中,通过求数据结构的一系列的操作的平均时间,来评价操作的代价。这样,即使这些操作中的某个单一操作的代价很高,也可以证明平均代价很低。摊还分析不涉及概率,它可以保证最坏情况下每个操作的平均性能。

摊还分析有三种常用的技术:

聚合分析,它确定$n$个操作的总代价的上界为$T(n)$,所以每个操作的平均代价为$\frac{{T(n)}}{n}$。每个操作都有相同的摊还代价。

核算法:分析每个操作的摊还代价,不同于聚合分析,每种操作的摊还代价是不同的,核算法将序列中较早的操作的余额作为“信用”储存起来,与数据结构中的特定对象相关联,在随后的操作中,储存的信用可以用来进行支付。

势能法:与核算法类似,也是分析每个操作的代价,但将势能作为一个整体存储,而与数据结构中的某个对象无关。

一、聚合分析

以栈操作为例:

存在3种操作:1、$push$ 2、$pop$ 3、$multipop$

直观地分析复杂度:因为栈的大小最大为$n$,所以$multipop$的最坏情况为$O(n)$,所以,由n个$push$,$pop$,$multipop$组成的操作序列的最坏代价为$O( n^2)$,因为序列可能包含$O(n)$个操作序列。

上面的分析给出的界并不是紧确界,实际上,在一个空栈上执行$n$个$push$, $pop$, $multipop$的操作序列,代价最多为$O(n)$。这是因为,当一个对象压入栈后,至多将其弹出一次。所以,对于一个非空的栈,可以执行的$pop$的次数(包含$multipop$中的$pop$)最多与$push$操作次数一样,即$n$次。所以,对任意的$n$,任意一个由$n$个$push$ , $pop$,$multipop$组成的操作序列,最多花费$O(n)$。所以,每个操作的摊还代价为$O(1)$。

二、核函数

核算法,对不同的操作赋予不同的费用,这个费用就是摊还代价。当一个操作的摊还代价超过实际代价的时候,将差额存入数据结构中的特定对象,存入的差额称为信用。对于后续操作中,摊还代价小于实际代价的情况,信用可以用来支付差额。

  因为希望通过分析摊还代价来说明每个操作的平均代价的很小,所以应该确保$n$个操作序列的摊还代价是实际代价的上界。如果${c_i}$ 表示第i个操作的真实代价,而${c'_i}$表示摊还代价,则对于任意的$n$,有:$\sum\limits_{i = 1}^n {{c_i}^\prime }  \ge \sum\limits_{i = 1}^n {{c_i}} $。因为信用就是摊还代价和实际代价的差值,即 $\sum\limits_{i = 1}^n {{c_i}^\prime }  - \sum\limits_{i = 1}^n {{c_i}} $,所以需要保持数据结构中的总信用永远为非负值。

依然以站操作为例:下面证明,如果按照摊还代价进行缴费,则可以支付任意的$n$个栈操作序列。在$push$操作时,共缴费2美元,其中1美元支付$push$的实际代价,将剩余的1美元存入插入的元素,作为信用。这样,每个插入的元素都具有1美元的信用。这1美元的信用,实际上是用来支付$pop$操作的预付费。当执行一个$pop$的时候,并不缴额外的费用,而是使用信用来支付实际代价。$multipop$也一样。所以,对任意的n个PUSH, POP, MULTIPOP组成的序列,总摊还代价为实际代价的上界,总摊还代价为$O(n)$。

三、势能法

势能法与核算法类似,但是势能法并不将预付代价表示为数据结构中特定对象的信用,而是表示为“势能”。势能是与整个数据结构相关联,而不是某个特定的对象。将势能释放,就可以支付未来操作的代价。

势能法如下:对一个初始数据结构 ${D_0}$执行$n$个操作。对于i = 1, 2,...,n, ${c_i}$表示第i个操作的实际代价, ${D_i}$表示在数据结构 ${D_{i - 1}}$上执行第i个操作得到的数据结构。势函数$\varphi $将每个数据结构${D_i}$映射到一个实数 $\varphi ({D_i})$,这个值就是关联到数据结构 的势。所以,第i个操作的摊还代价为${c'_i} = {c_i} + \varphi ({D_i}) - \varphi ({D_{i - 1}})$。每个操作的摊还代价等于其实际代价加上此操作引起的势能变化。

势能法其实就是核函数的总体分析。

再拿kmp算法是失配回退时使用的摊还分析技术:

这个可以用势能分析法来分析:
关于匹配指针的位置$cur$
操作A:匹配时,$cur +  + $;
操作B:失配时,$cur = next[cur - 1]$; (根据不同实现有所出入)
这个 $next[cur - 1] <  = cur - 1$ 是成立的。

根据势能分析($cur \ge 0$ 恒成立),我们可以证明,操作A的执行次数一定比操作B要多,两个操作都是$O(1)$。
而操作A的执行次数是很容易分析最坏上界是 $O(n)$
那么 $O(n) = T(A) \ge T(B)$
因此匹配时的时间复杂度$T(A + B) = O(n)$

其实上述操作类似于栈操作,直接类比进行复杂度分析即可。

算法导论17:摊还分析学习笔记(KMP复杂度证明)的更多相关文章

  1. MIT算法导论——第五讲.Linear Time Sort

    本栏目(Algorithms)下MIT算法导论专题是个人对网易公开课MIT算法导论的学习心得与笔记.所有内容均来自MIT公开课Introduction to Algorithms中Charles E. ...

  2. MIT算法导论——第一讲.Analysis of algorithm

    本栏目(Algorithms)下MIT算法导论专题是个人对网易公开课MIT算法导论的学习心得与笔记.所有内容均来自MIT公开课Introduction to Algorithms中Charles E. ...

  3. MIT算法导论——第二讲.Solving Recurrence

    本栏目(Algorithms)下MIT算法导论专题是个人对网易公开课MIT算法导论的学习心得与笔记.所有内容均来自MIT公开课Introduction to Algorithms中Charles E. ...

  4. MIT算法导论——第四讲.Quicksort

    本栏目(Algorithms)下MIT算法导论专题是个人对网易公开课MIT算法导论的学习心得与笔记.所有内容均来自MIT公开课Introduction to Algorithms中Charles E. ...

  5. MIT算法导论——第三讲.The Divide-and-Conquer

    本栏目(Algorithms)下MIT算法导论专题是个人对网易公开课MIT算法导论的学习心得与笔记.所有内容均来自MIT公开课Introduction to Algorithms中Charles E. ...

  6. MIT算法导论笔记

    详细MIT算法导论笔记 (网络链接) 第一讲:课程简介及算法分析 (Sheridan) 第二讲:渐近符号.递归及解法  (Sheridan) 第三讲:分治法(1)(Sheridan) 第四讲:快排及随 ...

  7. 算法导论笔记:18B树

    磁盘作为辅存,它的容量要比内存大得多,但是速度也要慢许多,下面就是磁盘的的结构图: 磁盘驱动器由一个或多个盘片组成,它们以固定的速度绕着主轴旋转,数据存储于盘片的表面,磁盘驱动器通过磁臂末尾的磁头来读 ...

  8. [置顶] 《算法导论》习题解答搬运&&学习笔记 索引目录

    开始学习<算法导论>了,虽然是本大部头,可能很难一下子看完,我还是会慢慢地研究的. 课后的习题和思考有些是很有挑战性的题目,我等蒻菜很难独立解决. 然后发现了Google上有挺全的algo ...

  9. 《算法导论》读书笔记之排序算法—Merge Sort 归并排序算法

    自从打ACM以来也算是用归并排序了好久,现在就写一篇博客来介绍一下这个算法吧 :) 图片来自维基百科,显示了完整的归并排序过程.例如数组{38, 27, 43, 3, 9, 82, 10}. 在算法导 ...

随机推荐

  1. 两种IO模式:Proactor与Reactor模式

    在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作. 在比较这两个模式之前,我们首先的搞明白 ...

  2. Qt在线讲座之QML脚本书写规范

    时间:2016年3月1日晚7:30 在线讲座:http://qtdream.com主页处就可以收看直播(详见主页提示) 參与对象:对Qt跨平台开发框架感兴趣的朋友们.当然了,假设你是大牛.也可以旁听一 ...

  3. 服务管理-tomcat

    Tomcat是Apache软件基金会的Jakarta项目中的一个核心项目,由Apache,Sun和其他一些公司及个人共同开发而成.由于有了Sun的参与和支持,最新的Servlet和JSP规范总是能在T ...

  4. 前端-DDoS攻击

    下面的脚本(略有修改)就会向受害网站发送大量的请求: function imgflood() { var TARGET = 'example.com' var URI = '/index.php?' ...

  5. git操作-如何把你的本地仓库放到GitHub已有仓库

    本地: 首先在你的本地git init 初始化一个仓库,然后git add . 将所有的文件都打包到仓库中,git -commit -m "first_commit" 此时是没有什 ...

  6. Java中的class类的cast方法和asSubclass方法

    一般来说cast是转型的意思,但是学java的时间也不短了,class类居然还有cast这个方法,这里来学习一下这个cast有何用. 第一次看到这个cast是在Spring的源码中, spring-f ...

  7. 图像处理之滤波---滤波在游戏中的应用boxfilter

    http://www.yxkfw.com/?p=7810 很有意思的全方位滤波应用 https://developer.nvidia.com/sites/default/files/akamai/ga ...

  8. 用Cocoapods集成XMPPFramework 遇 Module 'KissXML' not found 问题

    用Coacopods集成XMPPFramework完成后Command + B,报Module 'KissXML' not found 一般来说,通过Coacopods集成集成第三方框架,不会再有依赖 ...

  9. GCJ Qualification Round 2016 D题

    这题就是找规律.小数据还是挺容易想的.大数据得再深入分析一下. 题意挺绕的. 其实就是字符串转换.字符串只能有两种字母,L或G.给定K和C,就能通过规则生成目标字符串. 那么,如果知道了K和C,以及目 ...

  10. EasyDarwin开源流媒体服务器将select改为epoll的方法

    本文来自EasyDarwin团队Fantasy(fantasy(at)easydarwin.org) 一. EasyDarwin网络模型介绍 EventContext负责监听所有网络读写事件,Even ...