【问题标题】:Why does log appear so frequently in algorithmic complexity?为什么log在算法复杂度中出现的如此频繁?
【发布时间】:2014-12-11 00:13:45
【问题描述】:

这个问题是关于解决方案之间是否存在一些抽象的相似性,导致出现排序和搜索等登录问题。或者,更简单地说,为什么 log 在算法复杂度中出现的频率如此之高?

【问题讨论】:

    标签: algorithm sorting search asymptotic-complexity computer-science-theory


    【解决方案1】:

    当一个问题可以通过乘法因子反复缩小时,通常会出现对数。根据定义,将问题减小到恒定大小(例如大小 1)需要对数步数。

    一个典型的例子是重复消除一半的数据集,就像在二分搜索中所做的那样。这给了O(log2(n)) 复杂性。一些排序算法通过重复将数据集分成两半来工作,因此它们的时间复杂度也有对数项。

    更一般地说,对数经常出现在divide-and-conquer 递归关系的解中。请参阅 Wikipedia 中的 Master Theorem 进行进一步讨论。

    【讨论】:

      【解决方案2】:
      由于 boolean 逻辑,

      log 经常出现在计算机科学中。一切都可以简化为true vs false1 vs 0to be or not to be。如果您有 if 语句,您有一个选择,否则您有另一个选择。这可以应用于位(您有 0 或 1)或高影响问题,但有一个决定。就像在现实生活中一样,当你做出决定时,你并不关心如果你做出其他决定可能会发生的问题。这就是 log2(n) 经常出现的原因。

      然后,每个更复杂的情况(例如:从 3 个状态中选择一个可能的状态)可以简化为 log2(n) => 对数底没关系(常数不会影响函数的趋势 - 它具有相同的度数):

      • 数学证明:

                  loga(y)      1
        logx(y) = ------- = -------- * loga(y) = constant * loga(y)
                  loga(x)    loga(x)
        
      • 程序员的证明:

        switch(a) { 
            case 1: ... ;
            case 2: ... ;
            ...
            default: ... ;
        }
        

        类似于:

        if (a == 1) {  
            ...
        } else {
            if ( a == 2 ) {
                ...
            }
            ...
        }
        

        k 选项的switch 等效于k-1 if-else 语句,其中k = 常量)

      但为什么要登录?因为它是指数的倒数。在第一个决定中,您将大问题分成两部分。然后你只把“好”的一半分成两部分,等等。

      n      = n/2^0         // step 1
      n/2    = n/2^1         // step 2
      n/4    = n/2^2         // step 3
      n/8    = n/2^3         // step 4
      ...
      n/2^i  = n/2^i         // step i+1
      

      :有多少步?

      A:i+1(从0到i)

      因为当您找到想要的元素时它会停止(您无法做出其他决定)=> n = 2^i。如果我们应用对数,以 2 为底:

      log2(n) = log2(2^i)
      log2(n) = i
      => i + 1 = log2(n) + 1
      

      但常数不会影响复杂性 => 你有 ~log2(n) 个步骤

      【讨论】:

      • 这是一个有趣的论点。但是,实际上每个算法都使用if 语句,但只有一小部分算法的时间复杂度有日志,这不是真的吗?
      • 我没有提到if,因为它是在编程语言中。我提到if 作为决策声明(成为或不成为)。它甚至可以在二进制表示中看到(有时是“1”,有时是“0”),或者可以更普遍地看到它,因为它在二进制搜索中,但它每次都会创建逻辑分支。我同意你的观点,没有任何 if 语句会影响全局时间复杂度。
      • 这是一个非常有趣的答案。我还不清楚它与@NPE 提供的答案有何关系,因为它完全独立于减少问题的规模。它似乎适用于所有决策问题。
      【解决方案3】:

      log 在算法复杂度方面出现了很多,尤其是在递归算法中。

      我们以二分搜索为例。

      您有一个包含 100 个元素的排序数组 A,并且您正在寻找数字 15..

      在二分搜索中,您将查看中间元素 (50) 并将其与 15 进行比较。如果元素大于 15,则您会找到介于 50 和 100 之间的中间元素,即 75.. 并再次比较..如果 15 大于 75 处的元素,那么您查看 75 到 100 之间的元素,即元素 87...您继续执行此操作,直到找到该元素或直到没有更多中间数字...

      每次您执行这种检查中间数的方法时,您都会将剩余要搜索的元素总数减半..

      所以第一遍会给你 O(n/2) 复杂度.. 下一遍将是 O(n/4)... O(n/8) 等等.. 为了表示这种模式,我们使用日志..

      因为我们在每次通过成为对数基的算法时将要搜索的元素数量减少一半,所以二分搜索将产生 O(log2(n)) 复杂度

      大多数算法都试图通过将原始数据分解为单独的部分来解决,从而将操作数量“减少”到尽可能少,这就是日志如此频繁出现的原因

      【讨论】:

        猜你喜欢
        • 2011-09-03
        • 2018-11-26
        • 1970-01-01
        • 2021-11-11
        • 1970-01-01
        • 2013-11-09
        • 2012-02-27
        • 2021-06-22
        • 1970-01-01
        相关资源
        最近更新 更多