Recherches dans un tableau - séquentielle et dichotomique
Transcription
Recherches dans un tableau - séquentielle et dichotomique
Recherches dans un tableau Stéphane Gonnord Recherches dans un tableau séquentielle et dichotomique Plan Recherche séquentielle Le problème Positions True/False Stéphane Gonnord Recherche dichotomique Principe Différentes implémentations Complexité, correction [email protected] www.mp933.fr Lycée du parc - Lyon Vendredi 22 (et 29 ?) novembre 2013 Lycée du parc Recherches dans un tableau Plan Stéphane Gonnord 1. Recherche séquentielle I I I Présence d’un élément ; positions. Sortie prématurée... ou pas ? Correction, complexité. 2. Recherche dichotomique I I I I Principe. Mise en œuvre. Sortie prématurée... ou pas ? Correction, complexité. Plan Recherche séquentielle Le problème Positions True/False Recherche dichotomique Principe Différentes implémentations Complexité, correction Le problème Est-ce qu’un objet x appartient à un tableau t ? I Deux types de réponse : I True/False Recherches dans un tableau Stéphane Gonnord Plan Recherche séquentielle Le problème Positions I I Tableau des positions (éventuelles) True/False : I I Je parcours tous les éléments de t, et je note la présence éventuelle de x. Dès que je vois x, je hurle qu’il est présent et le travail est fini. I Positions : je parcours tous les indices, et je note les positions où je trouve x. I Une première solution excellente/misérable : def appartient1(x, t): return x in t True/False Recherche dichotomique Principe Différentes implémentations Complexité, correction Positions où on trouve l’objet I Fastoche... I À comprendre, et savoir refaire les yeux fermés... Mais merci d’avoir tout de même ce poly avec vous au prochain tp, au cazou. I Et donc, voici le code : Recherches dans un tableau Stéphane Gonnord Plan Recherche séquentielle Le problème Positions True/False Recherche dichotomique Principe def positions(x, t): """ Calcule les positions de x dans t""" Différentes implémentations Complexité, correction pos = [] # où seront stockées les positions for i in range(len(t)): if t[i] == x: pos.append(i) return pos True/False avec return interne I Dès qu’on voit x, on quitte le programme via return. On ne retourne False qu’après avoir tout parcouru. Recherches dans un tableau Stéphane Gonnord Plan Recherche séquentielle I Code : I def appartient2(x, t): Recherche dichotomique """Appartenance à un tableau. On sort dès que possible""" for y in t: if y == x: return True # surtout pas de else ! return False # Attention à l’indentation Complexité : de 1 à n = |t | accès au tableau. I Correction/validité ? Le problème Positions True/False Principe Différentes implémentations Complexité, correction True/False avec return final Recherches dans un tableau Stéphane Gonnord I Dès qu’on voit x, « on le note »... dans un booléen. I Code : I def appartient3(x, t): """Appartenance à un tableau. Recherche dichotomique On le parcourt complètement""" vu = False for y in t: if y == x: vu = True # toujours pas de else... return vu Complexité : systématiquement n = |t | accès (moins Plan Recherche séquentielle Le problème Positions True/False Principe Différentes implémentations Complexité, correction bien, donc). I Correction/validité ? True/False avec return final : mieux ! I I I Dès qu’on voit x, « on le note »... dans un booléen... et on quitte la boucle ! Mais comment donc ? Code : Recherches dans un tableau Stéphane Gonnord Plan Recherche séquentielle Le problème Positions True/False Recherche dichotomique I def appartient4(x, t): """Appartenance à un tableau. On sort de la boucle dès que possible""" vu = False indice = 0 while not(vu) and indice<len(t): if t[indice] == x: vu = True indice = indice+1 # attention à l’indentation return vu Complexité : de 1 à n = |t | accès. I Correction/validité ? Principe Différentes implémentations Complexité, correction Principe de la recherche dichotomique I S’applique à un tableau trié. I Vu de loin : I appartient(Winehouse, [Abba,...,ZZtop]) ? I I 9 n vs ln n ; 10 vs. 30. D’un peu plus près : I I I On tient à jour un intervalle de recherche dans le tableau. Il (sa longueur) est divisé(e) par deux à chaque étape. Jusqu’à ce que... I I on trouve Amy ! ou on constate l’absence. Recherches dans un tableau Stéphane Gonnord Plan Recherche séquentielle Le problème Positions True/False Recherche dichotomique Principe Différentes implémentations Complexité, correction Recherches dans un tableau Plus précisément I Stéphane Gonnord On tient à jour deux indices indiquant le début (d) et la fin (f ) de la plage considérée. I Initialisation : d, f = 0, len(t)-1 I Nombre d’éléments de la plage de travail ? Plan Recherche séquentielle Le problème Positions True/False Recherche dichotomique f −d +1 Principe Différentes implémentations Complexité, correction (piquets, intervalles...) I Indice « central » ? m= I f +d +1 2 Intervalle pour continuer ? [d , m − 1] ou [m + 1, f ] L’algorithme Entrées : b, T d , f ← 0, |T | − 1 tant que f > d faire si f − d est pair alors f m ← d+ 2 sinon m ← d +2f +1 si T [m] = b alors Résultat : True si T [m] > b alors f ← m − 1 # continuer à gauche sinon d ← m + 1 # continuer à droite # Ici, f = d (il reste un élément) ou f = d − 1 (il n’y a plus rien) si d = f et T [d ] = b alors Résultat : True Résultat : False Recherches dans un tableau Stéphane Gonnord Plan Recherche séquentielle Le problème Positions True/False Recherche dichotomique Principe Différentes implémentations Complexité, correction Implémentation directe Recherches dans un tableau Stéphane Gonnord Plan def recherche_dichotomique(b, t): Recherche séquentielle """ Recherche dichotomique dans un tableau trié""" d, f = 0, len(t)-1 Recherche while f > d: dichotomique m = (d+f+1)//2 if t[m] == b: return True if t[m] > b: f = m-1 else: d = m+1 if d == f and t[d] == b: return True return False Le problème Positions True/False Principe Différentes implémentations Complexité, correction Pareil... sans return prématuré Recherches dans un tableau Stéphane Gonnord Plan def recherche_dichotomique_bis(b, t): Recherche """ Recherche dichotomique dans un tableau trié""" séquentielle d, f = 0, len(t)-1 j_ai_trouve = False Recherche while not(j_ai_trouve) and (f > d): dichotomique m = (d+f+1)//2 if t[m] == b: j_ai_trouve = True else: if t[m] > b: f = m-1 else: d = m+1 if d == f and t[d] == b: j_ai_trouve = True return j_ai_trouve Le problème Positions True/False Principe Différentes implémentations Complexité, correction Et en récursif ? Recherches dans un tableau Stéphane Gonnord Plan def dicho_ter(but, t, debut, fin): Recherche séquentielle """ Recherche dichotomique récursive dans une zone d’un tableau trié""" Recherche if debut > fin: dichotomique # peut arriver du fait des appels récursifs return False if debut == fin: return t[debut] == but milieu = (debut+fin+1)//2 if t[milieu] == but: return True if t[milieu] < but: return dicho_ter(but, t, milieu+1, fin) return dicho_ter(but, t, debut, milieu-1) Le problème Positions True/False Principe Différentes implémentations Complexité, correction Cryptique ! On peut faire encore mieux... (pire ?) Recherches dans un tableau Stéphane Gonnord Plan Recherche def dicho_grumf(but, t, debut, fin): séquentielle return (debut <= fin) and\ ((debut == fin and t[debut] == but) True/False or Recherche dichotomique (debut < fin and ((t[(debut+fin+1)//2]==but) or (t[(debut+fin+1)//2]>but and dicho_grumf(but,t,debut,(debut+fin-1)//2)) or (t[(debut+fin+1)//2]<but and dicho_grumf(but, t,(debut+fin+3)//2,fin))))) Le problème Positions Principe Différentes implémentations Complexité, correction Recherches dans un tableau Complexité Stéphane Gonnord I Au départ : n éléments à traiter. I À chaque étape supplémentaire : la longueur est divisée par deux. Plan Recherche séquentielle Le problème Positions I True/False LA (une) bonne propriété : « Après k passages dans la boucle, f − d + 1 ≤ I Preuve : par récurrence. I Conséquence : une complexité « en ln n ». I C’est vraiment mieux que n ? Ben oui, vraiment ! n 2k » Recherche dichotomique Principe Différentes implémentations Complexité, correction Recherches dans un tableau Correction I I I I Stéphane Gonnord Invariant : « T [debut ] ≤ b ≤ T [fin] » Conséquence : si b est présent dans t, on va le trouver. Et sinon ? Cet invariant est faux ! On peut alors modifier le code... ou l’invariant ! Plan Recherche séquentielle Le problème Positions True/False Recherche dichotomique Principe Différentes implémentations Complexité, correction Merci de votre attention !