zoukankan      html  css  js  c++  java
  • 算法设计 分析篇(摊销分析)

    摊销分析

    摊销是一种,功过相抵的思想:

    ①中国古代,某大臣因为犯错,看在立下汗马功劳的份上,从轻发落。

    ②图灵被发现时个同性恋者,但因破解了德国海军密码,抵消罪过。

    摊销分析vs平均情况分析

    以一场篮球比赛为例。

    平均情况分析:比赛结束后一个队伍的得分就是所有队员得分的总分,除以队员数,就是每个队员平均得分。

    摊销分析:针对的是最坏情况下的平均,既每个队员表现的都是平时训练时的最差水平

    摊销分析(最差情况下的平均)≠ 平均情况分析!

    摊销分析vs最坏时间复杂性分析

    1.最坏时间复杂性分析:分析算法的最坏时间复杂度。

    2.摊销分析:连续执行n次最坏情况分析可能没有反应现实,因为特定的算法和数据结构,最坏情况不一定连续发生。

    摊销分析(执行n次平均)≠ 最坏时间复杂性分析(单次)

    摊销分析的目的:

    找出算法进行一系列操作时,在最坏情况下一个操作的平均成本,主要从算法的执行步骤,算法的数据结构两个方面分析。

    概率分析vs摊销分析

    概率分析:

    1.考虑算法平均执行时间

    2.考虑算法的所有可能输入

    3.可能涉及使用概率,称为期望运行时间

    摊销分析:

    1.执行步骤中的平均最坏情况下的性能

    2.针对某一个数据结构的操作

    3.不涉及概率问题

    摊销分析的三种方法:

       聚类法   

    先求出合计,然后求平均。求出n个操作的总代价上界T(n),每个操作的摊销代价T(n)/n。

       简单    

       常用

       会计法

    计算每个操作的摊销成本,累加每个个体操作的摊销成本,得到一组操作的总摊销成本。 

       复杂
       势能法 类似记账,存款不是某一操作的,而是整个数据结构的势。

       可靠

       准确

    方法一:聚类分析

    栈操作的聚类分析,核心思想

    对数据结构共有n个操作,最坏情况下:

    操作1:t1

    操作2:t2

    操作3:t3

    .

    .

    .

    操作n:tn                      

    T(n)=t1+t2+...+tn

    摊销代价T(n)/n

    栈操作的聚类分析:

    栈的主要特性为先进后出,主要操作有压栈(push)和出栈(pop);

    PUSH(S,x):将x压入栈S,时间成本O(1);

    POP(S):将栈顶元素弹出,时间成本O(1);

    MULTIPOP(S,k):将栈S中k个元素连续弹出,如果元素不到k个,则一直将栈谈空为止,操作成本min(|S|,k);

    提问:假如我们进行了一组压栈,出栈的操作,一共n次,最坏情况下,n次操作的成本是多少?

    聚类分析:

    由于栈这种数据结构如果进行了n次push操作,则pop操作的次数不可能大于n次,所以最坏的情况是进行了n-1次push操作,最后一次执行MULTIPOP。

    操作成本为2(n-1)次。一组n次PUSH、MULTIPOP操作的总成本为O(n),分摊到n个操作上,每个操作的摊销成本只有O(1);

    注:

    因为不知到PUSH、MULTIPOP各进行了多少次,无法单独计算每个操作的成本,但可以计算出总成本的上限。适合使用聚类分析。

    这种将一类操作聚集在一起进行总成本分析,然后平坦到每个操作上的思想,就是聚类分析。

    二进制计数器的聚类分析

    所有时钟计数器抽象层面上看成一个二进制计数器,一个n位的二进制计数器用数组A[n-1]来表示,A[0]为最低有效位,A[n-1]为最高有效位。

    从0开始往上计数,到2的n次方为止,计数过程中,不同字位可能发生变化,1变0,0变1,假定每次反转成本为1。

    如0111,加一之后为1000,翻转了4位,则这次操作成本为4。

    递增函数实现如下:

    INCREMENT(A)
    i=0;
    while(i<n&&A[i]=1){
      A[i]=0;
      i++;  
    }
    
    if(i<n){
      A[i]=1;  
    }

    计数到2的n次方,总共递增2的n次,在这n次递增操作中,字位翻转总数

    n(1+1/2+1/4+1/8+...1/2^n)=2n

    所以n次递增操作的成本只用O(n),平坦之后,每次的操作成本为O(1)。

     方法二:会计分析
    聚类分析的特点是将所有操作看作一个整体,计算总成本,用总成本除以操作数获得摊销成本。另一种方法就是,分别计算每个操作的成本,然后累加再平均,这就是会计分析。

    会计分析和聚类分析之间有个显著的不同:聚类分析的所有操作摊销成本是一样的,而会计分析里不同操作可以有不同的摊销成本。

    以栈为例,当压入一个元素时,实际成本为1,但压进去的总归要弹出来,它必然还有个弹出的成本。现在我们将一个操作现在和以后产生的成本总计下来,压栈的摊销成本为2。而后续POP和MULTIPOP的成本已经考虑过了,所以摊销成本为0。

    所以,对于一个n个操作的序列,总摊销成本最多为2n,因此总摊销成本为O(n),单个操作的摊销成本为O(1)。

    方法三:势能分析

    会计分析中,将未来可能产生的成本记录下来,称为信用,存放在个体操作中。这并不是唯一方法,将信用存放在整个数据结构中供所有元素共享,存放在数据结构中的信用,可以看作一种潜在的支付能力,我们称为势能,这种分析方法被称为势能分析。

  • 相关阅读:
    Java实现 LeetCode 30 串联所有单词的子串
    Java实现 LeetCode 29 两数相除
    Java实现 LeetCode 29 两数相除
    Java实现 LeetCode 29 两数相除
    Java实现 LeetCode 28 实现strStr()
    Java实现 LeetCode 28 实现strStr()
    Java实现 LeetCode 28 实现strStr()
    Java实现 LeetCode 27 移除元素
    Java实现 LeetCode 27 移除元素
    字符编码终极笔记:ASCII、Unicode、UTF-8、UTF-16、UCS、BOM、Endian
  • 原文地址:https://www.cnblogs.com/SeekHit/p/4977678.html
Copyright © 2011-2022 走看看