【问题标题】:Time complexity in backtracking algorithm回溯算法的时间复杂度
【发布时间】:2014-05-08 15:09:10
【问题描述】:

我要计算这个递归函数的最坏情况,时间复杂度。

list 是 m*n 个片段的列表。

matrix 是一个 mxn 的矩阵,用来填充这个和平。

Backtrack(list, matrix):
  if(matrix is complete) //O(1)
     return true
  from the list of m*n pieces, make a list of candidatePieces to put in the matrix. // O(m*n)
  for every candidatePiece // Worst case of n*m calls
      Put that piece in the matrix // O(1)
      if(Backtrack(list, matrix) is true)
           return true

我猜这个公式是这样的:

T(n*m) = T(n*m - 1) + O(n*m) + O(1) = T(n*m - 1) + O(n*m)

这是正确的吗?

我不能使用主定理,我可以使用其他方法来获得封闭公式吗?

【问题讨论】:

  • 你有没有从矩阵中取出东西?候选棋子永远不进去吗? matrix is complete什么时候返回true
  • 我问的原因是,for every candidatePiece 循环如果从未真正回溯,似乎毫无意义,这似乎是 Ashlynd 所假设的。

标签: time-complexity proof


【解决方案1】:

如果你解开你的公式,你会得到

T(n*m) = T(n*m-1)+O(n*m) = T(n*m-2)+O(n*m-1) + O(n*m) = ...
= O(n*m) + O(n*m-1) + O(n*m-2) +... + O(1) =>  ~ O(n^2*m^2)

但我想知道该算法是否完整?它似乎根本不返回 false。

【讨论】:

    【解决方案2】:

    所以我们有:

    Backtrack(list, matrix):
      if(matrix is complete) //O(1)
         return true
      from the list of m*n pieces, make a list of candidatePieces to put in the matrix. // O(m*n)
      for every candidatePiece // Worst case of n*m calls
          Put that piece in the matrix // O(1)
          if(Backtrack(list, matrix) is true)
               return true
    

    我们假设最坏情况下的行为,一些matrix is complete 尽可能长时间地为假。我将假设这是直到 O(n·m) 插入。

    所以考虑for every candidatePiece。为了获得第二个项目,您需要 Backtrack(list, matrix) is true 至少为 false 一次。这需要除return true 之外的终止。作为这样做的唯一方法需要耗尽循环,并且需要耗尽循环(等等),这只有在 candidatePieceempty 时才会发生。

    我认为碎片只能使用一次。在这种情况下,矩阵中有O(n·m) 的东西。这意味着matrix is complete 已经返回true,所以这实际上不会让循环再次运行。

    如果碎片没有用完,这显然也是正确的。

    然后我们可以简化为

    Backtrack(list, matrix):
      if(matrix is complete)
         return true
    
      if(candidatePiece is not empty)
          Put the first piece in the matrix
    
          if(Backtrack(list, matrix) is true)
               return true
    

    那么我们有

    T(n·m) = T(n·m - 1) + O(n·m)
    

    正如你所说,这导致了阿莎琳德的回答。


    假设matrix is complete 可以返回 false,即使矩阵已满。还假设碎片用完了,所以矩阵永远不会过满。我还假设适当地删除了碎片。

    • 最外层循环(循环 0)花费 O(n·m) 并运行内部循环(循环 1)n·m 次。

    • 内部循环(循环 1)花费 O(n·m - 1) 并运行内部循环(循环 2)n·m -1 次。

    • ...

    • 循环 n·m - 1 花费 1 并运行循环 n·m 一次。

    • 循环n·m 花费0(调用开销进入循环n·m - 1)并终止。

    因此,设T(n·m) 为循环 0 的成本,T(0) 为循环 n·m 的成本。

    T(x) = O(x) + x · T(x - 1)
    

    WolframAlpha solves this to be O(Γ(x+1) + x·Γ(x, 1))

    根据一些研究,这等于

    O(x! + x· [ (x-1)! · e⁻¹ · eₓ₋₁(1) ])
    
    = O(x!) + O(x· eₓ₋₁(1))
    
    = O(x!) + O(x· ∑ 1/k! from k=0 to x-1)
    
    = O(x!)
    

    所以对于x = n·m,我们正在谈论O((n·m)!) 时间。这很糟糕:/。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-21
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      相关资源
      最近更新 更多