# Cour 2 -- Algorithme ###### tags `cour` `M1 S1` `Algorithme` [Somaire](/ueYXUIJIQ6C6hcYzKYeojA#)\ [precedent](/129McedVTHKxfO4OH71UbA) > [time= 14 sept 2020] [TOC] ## Backtracking Les agorithme de backtracking sont souvent très inéficace. :::success **Le backtracking** est une stratégie récursive ou on parcour un "arbre" des configurations. On s'arrete dès qu'on rencontre un impossibilité. ::: ### Jeux des N reines Dans le cas des N reines impossibilité équivaut à placer une reine dans une case interdite. On revient en arrière "dans l'arbre". Un sommet de l'arbre est égal à une éxécution de la fonction récursive.\ Ses fils vaut un apelle récursifs fais en cour d'éxécutions. ++Exemple:++\ Qu'est ce qu'une configuration?\ *Un tableau de taille N* ![](https://i.imgur.com/PSRz7Pt.png) #### Relation de récurence pour les 8 reines L est la liste de la config\ N la taille du probème NxN $$ Reine(L, N) = \begin{cases} \text{Vrai } &\text{si} |L| = N\\ \bigvee\limits_{i=0}^{n} \: Reine(L + [i], N) \:\land\: Valide(L + [i]) &\ \end{cases} $$ Fonction de vadité ![](https://i.imgur.com/8tNXxhB.png) Algorithme ```python def valide(L, c): """ test si la colone et les 2 diagonales sont valide L :list reine déja placées c :int la colone a tester """ for i in range(len(L)): test_set = { c, c - (len(L) - i), c + (len(L) - i) } if L[i] in test_set: return False return True def reines(L, N): """ L : list reine déja placées N : int taille de l'échiquier """ if len(L) == N: return True for c in range(N): # essayons de placer la reine en colonne c # sur la ligne len(L) # on a pas besoin de test la ligne # car on ajoute au fur et a mesure if valide(L, c) and reines(L + [c], N): return true return False ``` ##### Compléxité De l'ordre de **N^N^ x N^2^** - N^N^ est le nombre de noeud visité dans l'arbre des configurations - Car on a une arrité des noeuds N (N appels récursifs) - profondeur de l'arbre = N\ A chaque niveau on ajoute une reine - le travail de vérification de la validité (cout de N^2^) ++Que représente N++^N^ ?\ N = 10 -> 10^10^ $\approx$ 2^30^\ N = 20 -> 20^20^ a peut pres 10^9^ jours ### ++Probleme 2:++ Subset Sum - ++En entrée:++ \ Un ensemble de nombre positif L une valeur X - ++En sortie:++ \ Est-il possible d'obtenir X comme la somme d'un sous-ensemble de L? Ex: L = [2, 8, 3, 11, 24, 5]\ Pour X = 18\ on peut avec 2 + 8 + 3 + 5 = 18 ++Algorithme possible++: essayer tout les sous ensembles de L.\ Si |L| = N il y a 2^N^ sous-ensembles. Stratégie proposée: ``` On regarde le premier élément si il est < X: on essaie de le prendre et puis si non on complète avec X = X - a si ca n'a pas marché on coninue avec l'élément suivant ``` Relation de récurence: $$ S(L, X) = \begin{cases} \text{Vrai} & \text{si } X = 0\\ \text{Faux} & \text{si } X < 0\\ \text{Faux} & \text{si } |L| = 0 \: \land \: X>0\\ S(L[1:], X-L[0]) \: \lor\: S(L[1:], X) \end{cases} $$ Algorithme ```python= def S(l, x): if x == 0: return True elif x < 0: return False elif l == []: return x == 0 avec = s(l[1:], x - l[0]) if avec: return True; return s(l[1:], x) ``` ![](https://i.imgur.com/kFJ4Uoc.png) ++compléxité:++ - Arbre avec une arrité 2 (avec / sans) - profondeur: taille de la liste Nombre de sommets: 2^|L|^\ Si on néglige la soustaction (x - L[0], *ligne 9*) qui n'est pas en temps constant La compléxité est donc de l'ordre de **2^N^** si N = |L| [suivant](/IdYcb7YBTBSveQ_t0efkLw)