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 !

Documents pareils