Comment calculer la complexité temporelle de ces algorithmes de retour en arrière et ont-ils la même complexité temporelle? Si différent comment? Veuillez expliquer en détail et merci pour l'aide.
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
}
}
}
Je suis un peu confus, quant à Word Break (b), la complexité est O (2n) mais pour Hamilton, son cycle est différent et il en est de même pour l’impression de permutations différentes de la même chaîne, puis pour la résolution du problème n reens.
O(N!)
dans le pire des casO(2^N)
O(N!)
Remarque: pour WordBreak, il existe une solution de programmation dynamique O (N ^ 2).
Dans le cycle hamiltonien, dans chaque appel récursif, l'un des sommets restants est sélectionné dans le pire des cas. Dans chaque appel récursif, le facteur de branche diminue de 1. Dans ce cas, la récursivité peut être assimilée à n boucles imbriquées où, dans chaque boucle, le nombre d'itérations diminue de un. D'où la complexité temporelle est donnée par:
T(N) = N*(T(N-1) + O(1))
T(N) = N*(N-1)*(N-2).. = O(N!)
De même dans NQueens, chaque fois que le facteur de branchement diminue de 1 ou plus, mais pas beaucoup, d’où la limite supérieure de O(N!)
Pour WordBreak, c'est plus compliqué, mais je peux vous donner une idée approximative. Dans WordBreak, chaque caractère de la chaîne a deux choix dans le pire des cas, soit être la dernière lettre du mot précédent, soit la première lettre d'un nouveau mot, d'où le facteur de ramification est 2. Par conséquent, pour WordBreak et SegmentString T(N) = O(2^N)
Algo backtracking:
problème n-reine: O (n!)
problème de coloration des graphes: O (nm ^ n) // où n = non. du sommet, m = non. de couleur utilisée
cycle d'hamilton: O (N!)
WordBreak et StringSegment: O (2 ^ N)
problème de somme de sous-ensembles: O(nW)