Как рассчитать сложность времени алгоритма возврата?
Как рассчитать сложность времени для этих алгоритмов обратного отслеживания и имеют ли они такую же временную сложность? Если разные способы? Пожалуйста, объясните подробно и спасибо за помощь.
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 queens.
Ответы
Ответ 1
Короче:
- Гамильтонов цикл:
O(N!)
в худшем случае
- WordBreak и StringSegment:
O(2^N)
- NQueens:
O(N!)
Примечание. Для WordBreak существует решение динамического программирования O (N ^ 2).
Подробнее:
-
В гамильтоновом цикле в каждом рекурсивном вызове одна из оставшихся вершин выбирается в худшем случае. В каждом рекурсивном вызове коэффициент ветвления уменьшается на 1. Рекурсия в этом случае может рассматриваться как n вложенных циклов, где в каждом цикле количество итераций уменьшается на единицу. Следовательно, временная сложность задается следующим образом:
T(N) = N*(T(N-1) + O(1))
T(N) = N*(N-1)*(N-2).. = O(N!)
-
Аналогично в NQueens каждый раз, когда коэффициент ветвления уменьшается на 1 или более, но не много, следовательно, верхняя граница O(N!)
-
Для WordBreak это сложнее, но я могу дать вам приблизительную идею. В WordBreak каждый символ строки имеет два варианта в худшем случае: либо быть последней буквой в предыдущем слове, либо быть первой буквой нового слова, поэтому коэффициент ветвления равен 2. Поэтому для WordBreak и SegmentString T(N) = O(2^N)
Ответ 2
Алгоритм обратной трассировки:
Проблема с n-королевой: O (n!)
проблема окраски графа: O (nm ^ n)//где n = нет. вершины, т = нет. используемого цвета
цикл гамильтона: O (N!)
WordBreak и StringSegment: O (2 ^ N)
проблема суммы подмножества: O (nW)