簡體   English   中英

如何計算回溯算法的時間復雜度?

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

如何計算這些回溯算法的時間復雜度,它們是否具有相同的時間復雜度? 如果不同怎么樣? 請詳細解釋並感謝您的幫助。

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
                }
            }
        }

我實際上有點困惑,因為Word Break(b)的復雜度是O(2 n )但是對於哈密爾頓循環它的不同,所以打印相同字符串的不同排列然后再次解決n皇后問題。

簡而言之:

  1. 哈密​​頓循環:在最壞的情況下為O(N!)
  2. WordBreak和StringSegment: O(2^N)
  3. NQueens: O(N!)

注意:對於WordBreak,有一個O(N ^ 2)動態編程解決方案。


更多細節:

  1. 在哈密頓循環中,在每次遞歸調用中,在最壞的情況下選擇剩余頂點之一。 在每次遞歸調用中,分支因子減少1.在這種情況下的遞歸可以被認為是n個嵌套循環,其中在每個循環中迭代次數減少1。 因此時間復雜度由下式給出:

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

  2. 同樣在NQueens中,每次分支因子減少1或更多,但不多,因此O(N!)的上限

  3. 對於WordBreak它更復雜,但我可以給你一個近似的想法。 在WordBreak中,字符串的每個字符在最壞的情況下有兩個選項,要么是前一個單詞中的最后一個字母,要么是新單詞的第一個字母,因此分支因子是2.因此對於WordBreak和SegmentString T(N) = O(2^N)

回溯算法:

n-queen問題: O(n!)

圖着色問題: O(nm ^ n) //其中n = no。 頂點,m =否。 使用的顏色

漢密爾頓周期: O(N!)

WordBreak和StringSegment: O(2 ^ N)

子集和問題: O(nW)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM