[算法分析笔记] 竞争分析(Competive Analysis)

竞争分析的定义

对于一种在线算法A, 如果存在一个常数K, 对于任何序列S的操作的成本, C A ( S ) < = α . C o p t ( S ) + K C_A(S)<= \alpha.C_{opt}(S)+K CA(S)<=α.Copt(S)+K, 则我们可以称算法A为 α \alpha α阶竞争的,此处, C o p t C_{opt} Copt是最优算法的成本,又称上帝算法,假设该算法可以预见所有的后续操作并给出一个最优的算法。

这意味着,如果最优算法(上帝)可以做的更好,该 α \alpha α阶竞争的算法也可以相对的做的更好,而 α \alpha α阶竞争的算法性能不佳时,最优算法(上帝)也好不到那里去。他们的性能表现始终是同向的。

为了说明竞争分析的方法,我们要对一个在线算法进行分析,并证明该算法是 α \alpha α - 竞争的。

自组织列表

这个算法出现在算法大牛Danny Sleator和Bob Tarjan的论文里,感兴趣的小伙伴可以自行去搜索该论文。

定义:列表L包含n个元素,

  • 访问X元素的操作被定义为Access(X), 其成本是 r a n k L ( X ) rank_L(X) rankL(X)等于从L列表头到X的元素个数,假设每访问一个元素的代价为1, 每次都从列表头开始逐个搜索到需要访问的元素。
  • 列表L可以通过交换操作相邻位置的两个元素来改变顺序。每一次交换的代价是1。
    在这里插入图片描述
  • 在线算法A每次必须在立即访问操作的同事运行,且无法知道后续访问操作时什么。相对的,最优算法则是可以与之全部后续的访问操作,并将序列调整到最优状态的算法。
    此处我们介绍一种启发式算法:move-to-front,即在某元素被访问后,即可使用交换算法,将此元素移到队列的列首。所以,一次访问的代价是
    C o s t = 2. r a n k L ( X ) Cost=2.rank_L(X) Cost=2.rankL(X)
    这里要解释一下为什么是2倍的 r a n k L ( X ) rank_L(X) rankL(X), 其中一次是访问该元素的代价,另一次是交换该元素的队列首的代价。

竞争分析实例

此处我们就使用竞争分析来分析一下move-to-front(MTF)是否是 α \alpha α-竞争的。
C i = M T F C_i=MTF Ci=MTF算法的每次访问操作的代价 = 2. r a n k L i − 1 ( X ) =2.rank_{L_i-1}(X) =2.rankLi1(X)
C i ∗ = O P T C^*_i=OPT Ci=OPT算法的每次访问操作的代价 = r a n k L i − 1 ∗ ( X ) + t i =rank^*_{L_i-1}(X)+t_i =rankLi1(X)+ti 其中设 t i t_i ti是最优算法进行元素交换的代价

定义势能方程
Φ : L i → R \Phi:{L_i} \rightarrow R ΦLiR
Φ ( L i ) = 2 ∣ { ( x , y ) . x ⋉ L i y , a n d , y ⋉ L i ∗ x } ∣ \Phi(L_i)=2|\lbrace(x,y).x\ltimes _{L_i}y, and, y\ltimes_{L_i}^*x\rbrace| Φ(Li)=2∣{(x,y).xLiy,and,yLix}
= 2 × =2\times =2×#倒置数
此处解释一下集合 ∣ { ( x , y ) . x ⋉ L i y , a n d , y ⋉ L i ∗ x } ∣ |\lbrace(x,y).x\ltimes _{L_i}y, and, y\ltimes_{L_i}^*x\rbrace| {(x,y).xLiy,and,yLix}代表的是一组列表中的元素的集合, ⋉ \ltimes 是前序符号,表示x在y的前序,该组元素在MTF算法中的列表和最优算法中的列表的前后次序是颠倒的。
为了更清楚的来解释这个问题,我们来看一下下面这个例子。
在这里插入图片描述
上图中,L是MTF算法中 i 次访问前的列表序列, 而L是最优算法在 i 次访问前的序列。那逆序的元素对如下:
Φ ( L i ) = 2. ∣ ( E , C ) , ( E , A ) , ( E , D ) , ( E , B ) , ( B , D ) ∣ = 10 \Phi(L_i)=2.|{(E,C), (E,A), (E,D), (E,B), (B,D) }|=10 Φ(Li)=2.∣(E,C),(E,A),(E,D),(E,B),(B,D)=10
此处 Φ ( L i ) > = 0 ∀ i \Phi(L_i)>=0 \forall i Φ(Li)>=0∀i
Φ ( L 0 ) = 0 \Phi(L_0)=0 Φ(L0)=0 当MTF和OPT的起始列表是一样序列的
那对于一次交换,势能函数 Φ \Phi Φ的变化是多少呢?由交换操作的本质可知,每次交换可以产生或消除一对逆序元素。因此 Δ Φ = ± 2 \Delta\Phi=\pm2 ΔΦ=±2
那么,我们该如何来计算一次访问后的势能变化呢?为了解答这个问题,我们来定义一组集合如下:
A = { y ∈ l i : y ⋉ L i − 1 x , a n d , y ⋉ L i − 1 ∗ x } A=\lbrace y\in l_i: y\ltimes_{L_i-1} x , and, y \ltimes_{L_i-1}^*x\rbrace A={yli:yLi1x,and,yLi1x}
B = { y ∈ l i : y ⋉ L i − 1 x , a n d , y ⋊ L i − 1 ∗ x } B=\lbrace y\in l_i: y\ltimes_{L_i-1} x , and, y \rtimes_{L_i-1}^*x\rbrace B={yli:yLi1x,and,yLi1x}
C = { y ∈ l i : y ⋊ L i − 1 x , a n d , y ⋉ L i − 1 ∗ x } C=\lbrace y\in l_i: y\rtimes_{L_i-1} x , and, y \ltimes_{L_i-1}^*x\rbrace C={yli:yLi1x,and,yLi1x}
D = { y ∈ l i : y ⋊ L i − 1 x , a n d , y ⋊ L i − 1 ∗ x } D=\lbrace y\in l_i: y\rtimes_{L_i-1} x , and, y \rtimes_{L_i-1}^*x\rbrace D={yli:yLi1x,and,yLi1x}
为了更好的解释这组集合的含义,我们来看下图。
在列表 L i − 1 L_{i-1} Li1中, X元素位于图中所示的位置,X元素前的所有元素被分成
在这里插入图片描述
A和B两个集合,A集合中的元素在列表 L i − 1 ∗ L_{i-1}^* Li1中也位于X元素前,而B集合中的元素则在列表 L i − 1 ∗ L_{i-1}^* Li1中位于X元素之后。理解了A,B两个集合,则C,D两个集合就很容易了。
由此,我们可以定义在 L i − 1 L_{i-1} Li1中X的前序元素集合为AUB,X的后续元素集合为CUD。而在列表 L i − 1 ∗ L_{i-1}^* Li1中X的前序元素集合为AUC,X的后续元素的集合为BUD。
因此,r=|A|+|B|+1, r
=|A|+|C|+1,当MTF移动X元素到列表头时,会产生|A|组逆序,并消除了|B|组逆序。
同时,最优算法的每次交换元素可能产生少于1组逆序。
因此, Φ ( L i ) − Φ ( L i − 1 ) < = 2 ( ∣ A ∣ − ∣ B ∣ + t i ) \Phi (L_i)-\Phi (L_{i-1})<=2(|A|-|B|+t_i) Φ(Li)Φ(Li1)<=2(AB+ti)
此处我们使用平摊分析的代价公式来求第 i 次访问的代价的通式:
C ^ i = C i + Φ ( L i ) − Φ ( L i − 1 ) \hat C_i=C_i+\Phi (L_i)-\Phi (L_{i-1}) C^i=Ci+Φ(Li)Φ(Li1)
< = 2. r + 2. ( ∣ A ∣ − ∣ B ∣ + t i ) <=2.r+2.(|A|-|B|+t_i) <=2.r+2.(AB+ti)
r = ∣ A ∣ + ∣ B ∣ + 1 r=|A|+|B|+1 r=A+B+1 可得
上式 = 2. r + 2 ( ∣ A ∣ − ( r − 1 − ∣ A ∣ ) + t i ) =2.r+2(|A|-(r-1-|A|)+t_i) =2.r+2(A(r1A)+ti)
= 2. r + 4 ∣ A ∣ − 2. r + 2 + 2 t i =2.r+4|A|-2.r+2+2t_i =2.r+4∣A2.r+2+2ti
= 4. ∣ A ∣ + 2 + 2 t i =4.|A|+2+2t_i =4.∣A+2+2ti
r ∗ = ∣ A ∣ + ∣ C ∣ + 1 > = ∣ A ∣ + 1 r^*=|A|+|C|+1>=|A|+1 r=A+C+1>=A+1
上式 < = 4. ( r ∗ + t i ) = 4 C i ∗ <=4.(r^*+t_i)=4C_i^* <=4.(r+ti)=4Ci
接下来我们来求所有访问的代价总和如下。
C M T F ( S ) = Σ i = 1 ∣ s ∣ C i C_{MTF}(S)=\Sigma_{i=1}^{|s|}C_i CMTF(S)=Σi=1sCi
C ^ i = C i + Φ ( L i ) − Φ ( L i − 1 ) \hat C_i=C_i+\Phi (L_i)-\Phi (L_{i-1}) C^i=Ci+Φ(Li)Φ(Li1)可得 C i = C ^ i − Φ ( L i ) + Φ ( L i − 1 ) C_i=\hat C_i-\Phi (L_i)+\Phi (L_{i-1}) Ci=C^iΦ(Li)+Φ(Li1)代入上式可得
= Σ i = 1 ∣ s ∣ ( C ^ i + Φ ( L i − 1 ) − Φ ( L i ) ) =\Sigma_{i=1}^{|s|}(\hat C_i+\Phi(L_{i-1})-\Phi(L_i)) =Σi=1s(C^i+Φ(Li1)Φ(Li))
= Σ i = 1 ∣ s ∣ C ^ i + Φ ( L 0 ) − Φ ( L ∣ s ∣ ) =\Sigma_{i=1}^{|s|}\hat C_i+\Phi(L_0)-\Phi(L_{|s|}) =Σi=1sC^i+Φ(L0)Φ(Ls)
Φ ( L 0 ) = 0 \Phi(L_0)=0 Φ(L0)=0可得
= Σ i = 1 ∣ s ∣ C ^ i − Φ ( L ∣ s ∣ ) =\Sigma_{i=1}^{|s|}\hat C_i-\Phi(L_{|s|}) =Σi=1sC^iΦ(Ls)
之前我们已经推导出 C ^ i < = 4 C i ∗ \hat C_i <=4C_i^* C^i<=4Ci可得到
上式 < = Σ i = 1 ∣ s ∣ 4 C i ∗ − Φ ( L ∣ s ∣ ) <= \Sigma_{i=1}^{|s|} 4C_i^*-\Phi(L_{|s|}) <=Σi=1s4CiΦ(Ls)
< = 4. C o p t ( S ) <=4.C_{opt}(S) <=4.Copt(S)
以上证明MTF算法对于自组织队列而言是 4阶竞争的。这是一个很赞的证明,因为由此你可以发现MTF算法在任何情况下都不会比最优算法糟糕太多,换句话说如果在某种特定情况想最优算法可以做的更好,那MTF也可以相应的提升,而当MTF算法表现不好的时候,实际上最优算法也不会好到那里去,他们始终是可以相比较的。

此处值得一提的是,在Danny Sleator和Bob Tarjan的论文里,他们的算法将被访问的元素直接移动到列表的头部,而不是通过逐个交换到表头。因此,在他们的算法中移动到表头的代价是固定的,和该元素的位置无关,由此MTF算法可以进一步优化成 2阶竞争的。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程小白的逆袭日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值