简体   繁体   English

如何计算回溯算法的时间复杂度?

[英]How to calculate time complexity of backtracking algorithm?

How to calculate time complexity for these backtracking algorithms and do they have same time complexity? 如何计算这些回溯算法的时间复杂度,它们是否具有相同的时间复杂度? If different how? 如果不同怎么样? Kindly explain in detail and thanks for the help. 请详细解释并感谢您的帮助。

1. Hamiltonian cycle:

        bool hamCycleUtil(bool graph[V][V], int path[], int pos) {
            /* base case: If all vertices are included in Hamiltonian Cycle */
            if (pos == V) {
                // And if there is an edge from the last included vertex to the
                // first vertex
                if ( graph[ path[pos-1] ][ path[0] ] == 1 )
                    return true;
                else
                    return false;
            }

            // Try different vertices as a next candidate in Hamiltonian Cycle.
            // We don't try for 0 as we included 0 as starting point in in hamCycle()
            for (int v = 1; v < V; v++) {
                /* Check if this vertex can be added to Hamiltonian Cycle */
                if (isSafe(v, graph, path, pos)) {
                    path[pos] = v;

                    /* recur to construct rest of the path */
                    if (hamCycleUtil (graph, path, pos+1) == true)
                        return true;

                    /* If adding vertex v doesn't lead to a solution, then remove it */
                    path[pos] = -1;
                }
            }

            /* If no vertex can be added to Hamiltonian Cycle constructed so far, then return false */
            return false;
        }

2. Word break:

       a. bool wordBreak(string str) {
            int size = str.size();

            // Base case
            if (size == 0)
                return true;

            // Try all prefixes of lengths from 1 to size
            for (int i=1; i<=size; i++) {
                // The parameter for dictionaryContains is str.substr(0, i)
                // str.substr(0, i) which is prefix (of input string) of
                // length 'i'. We first check whether current prefix is in
                // dictionary. Then we recursively check for remaining string
                // str.substr(i, size-i) which is suffix of length size-i
                if (dictionaryContains( str.substr(0, i) ) && wordBreak( str.substr(i, size-i) ))
                    return true;
            }

            // If we have tried all prefixes and none of them worked
            return false;
        }
    b. String SegmentString(String input, Set<String> dict) {
           if (dict.contains(input)) return input;
           int len = input.length();
           for (int i = 1; i < len; i++) {
               String prefix = input.substring(0, i);
               if (dict.contains(prefix)) {
                   String suffix = input.substring(i, len);
                   String segSuffix = SegmentString(suffix, dict);
                   if (segSuffix != null) {
                       return prefix + " " + segSuffix;
                   }
               }
           }
           return null;
      }


3. N Queens:

        bool solveNQUtil(int board[N][N], int col) {
            /* base case: If all queens are placed then return true */
            if (col >= N)
                return true;

            /* Consider this column and try placing this queen in all rows one by one */
            for (int i = 0; i < N; i++) {
                /* Check if queen can be placed on board[i][col] */
                if ( isSafe(board, i, col) ) {
                    /* Place this queen in board[i][col] */
                    board[i][col] = 1;

                    /* recur to place rest of the queens */
                    if ( solveNQUtil(board, col + 1) == true )
                        return true;

                    /* If placing queen in board[i][col] doesn't lead to a solution then remove queen from board[i][col] */
                    board[i][col] = 0; // BACKTRACK
                }
            }
        }

I am actually confused a bit, as for Word Break(b) the complexity is O(2 n ) but for Hamiltonian cycle its different and so does for printing different permutations of the same string and then again for solving n queens problem. 我实际上有点困惑,因为Word Break(b)的复杂度是O(2 n )但是对于哈密尔顿循环它的不同,所以打印相同字符串的不同排列然后再次解决n皇后问题。

In short: 简而言之:

  1. Hamiltonian cycle : O(N!) in the worst case 哈密​​顿循环:在最坏的情况下为O(N!)
  2. WordBreak and StringSegment : O(2^N) WordBreak和StringSegment: O(2^N)
  3. NQueens : O(N!) NQueens: O(N!)

Note: For WordBreak there is an O(N^2) dynamic programming solution. 注意:对于WordBreak,有一个O(N ^ 2)动态编程解决方案。


More details: 更多细节:

  1. In Hamiltonian cycle, in each recursive call one of the remaining vertices is selected in the worst case. 在哈密顿循环中,在每次递归调用中,在最坏的情况下选择剩余顶点之一。 In each recursive call the branch factor decreases by 1. Recursion in this case can be thought of as n nested loops where in each loop the number of iterations decreases by one. 在每次递归调用中,分支因子减少1.在这种情况下的递归可以被认为是n个嵌套循环,其中在每个循环中迭代次数减少1。 Hence the time complexity is given by: 因此时间复杂度由下式给出:

    T(N) = N*(T(N-1) + O(1))
    T(N) = N*(N-1)*(N-2).. = O(N!)

  2. Similarly in NQueens, each time the branching factor decreases by 1 or more, but not much, hence the upper bound of O(N!) 同样在NQueens中,每次分支因子减少1或更多,但不多,因此O(N!)的上限

  3. For WordBreak it is more complicated but I can give you an approximate idea. 对于WordBreak它更复杂,但我可以给你一个近似的想法。 In WordBreak each character of the string has two choices in the worst case, either to be the last letter in the previous word, or to be the first letter of a new word, hence the branching factor is 2. Therefore for both WordBreak & SegmentString T(N) = O(2^N) 在WordBreak中,字符串的每个字符在最坏的情况下有两个选项,要么是前一个单词中的最后一个字母,要么是新单词的第一个字母,因此分支因子是2.因此对于WordBreak和SegmentString T(N) = O(2^N)

Backtracking algo: 回溯算法:

n-queen problem: O(n!) n-queen问题: O(n!)

graph coloring problem: O(nm^n) //where n=no. 图着色问题: O(nm ^ n) //其中n = no。 of vertex,m=no. 顶点,m =否。 of color used 使用的颜色

hamilton cycle: O(N!) 汉密尔顿周期: O(N!)

WordBreak and StringSegment: O(2^N) WordBreak和StringSegment: O(2 ^ N)

subset sum problem: O(nW) 子集和问题: O(nW)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM