Algorithmique.

publicité
BCPST 1B
2014/2015
Algorithmique.
1) Introduction.
Ce cours peut être déconnecté du cours de programmation en Python. Python sera un outil d’illustration,
mais ici nous présentons des algorithmes classiques et d’usage universel.
Nous nous intéresserons essentiellement à des problèmes simples posés sur des données numériques structurées dans une liste.
Nous verrons aussi des exemples d’algorithmes résolvant des problèmes sur les chaı̂nes de caractères, des
images ou permettant de simuler des variables aléatoires à l’aide d’un générateur de nombres pseudoaléatoires.
Commençons par donner les opérations constituant un algorithme (ce sont les règles du jeu) :
a) Lecture d’une valeur dans une variable ou dans un élément d’une liste.
b) Evaluation d’une expression numérique avec +, −, ∗ et /.
c) Affectation d’une valeur à une variable ou à un élément d’une liste. (on utilisera la notation : ←)
d) Comparaison de deux valeurs numériques <, = ,6= et >
e) Branchement conditionnel (Si ...)
f) Boucle itérative (Pour ...)
g) Boucle conditionnelle (Tant que ...)
Dans les algorithmes étudiés nous n’utiliserons (”presque”) que cela,
Les valeurs numériques seront entières ou réelles.
Remarque : Pour s’entrainer avec la numérotation Python nous utiliserons la numérotation de 0 à n − 1.
L(0 : n − 1) = (L(0), L(1), ...., L(n − 1)) pour une liste de longueur n,
T (0 : n − 1) =0 T (0)T (1) · · · T (n − 1)0 pour une chaı̂ne de caractères de longueur n.
Exemple :
Entrées : n : un entier.
Variables : i : un entier, x : un réel, L(0 : n − 1) : une liste de nombre réels.
Début
i←0
Tant que i < n faire
L(i) ← i ∗ i
i←i+1
x ← x + L(0)
Pour i allant de 1 à n − 1 faire
x ← L(i)
Sorties : La valeur de x
Remarque importante : L’ensemble des algorithmes de ce cours sont explicitement au programme.
Vous devez être capable de tous les réécrire et de les expliquer.
1
2) Recherches dans une liste.
• Recherche d’une valeur dans une liste
Soit n un entier, x un réel et L une liste de n réels.
On suppose que x est présent au moins une fois dans la liste.
L’algorithme suivant permet de savoir où est le premier x de la liste.
Algorithme 1 : Recherche d’une valeur dans une liste
Entrées : n : un entier, x : un réel, L(0 : n − 1) : une liste de nombre réels,
Variables : i : un entier.
Début
i←0
Tant que L(i) 6= x faire
i←i+1
Sorties : i
Remarques sur le nombre d’opérations nécessaires :
- Le nombre de comparaisons (minimum = 1, maximum = n),
- Le nombre d’affectations = au nombre de comparaisons,
n+1
- Nombre moyen d’affectations :
.
2
On dit que la complexité de cet algorithme est en O(n), cela signifie que le nombre d’opérations nécessaires
est proportionnel à la taille des données.
Si on multiplie par 10 la taille de la liste à l’entrée de cet algorithme le nombre d’opérations nécessaires
sera multiplié par 10. Nous verrons plus tard que cette complexité peut ne pas être linéaire.
Traduction en une fonction Python :
def recherche(x,L):
"""float or in,list->int
L est une liste de flottants ou d’entiers contenant x
retourne le plus petit i tel x=L[i]"""
i=0
while x!=L[i]:
i=i+1
return i
• Recherche du maximum des valeurs dans une liste.
Soit n un entier, L une liste de n réels.
L’algorithme suivant permet de calculer le maximum des valeurs de la liste :
Algorithme 2 : Calcul du maximum des valeurs dans une liste.
Entrées : n un entier, L(0 : n − 1) : une liste de nombre réels.
Variables : M un réel
Début
M ← L(0)
Pour i allant de 1 à n − 1 faire
Si L(i) > M alors
M ← L(i)
Sorties : La valeur de M
2
Remarques sur le nombre d’opérations nécessaires :
- Le nombre de comparaisons : n − 1
- Le nombre d’affectations (Minimum : 1, Maximum : n)
- Nombre moyen d’affectations : Pas facile.
Avec un peu de connaissance en probabilité on montre que pour n grand ce nombre vaut à peu près ln(n)
def maximum(L):
"""List->float or int
L est une liste de flottants ou d’entiers
retourne la plus grande valeur de L"""
M=L[0]
for k in range(len(L)):
if M<L[k]:
M=L[k]
return M
• Recherche d’un mot dans une chaı̂ne de caractères.
Position du problème :
On cherche la position d’un mot dans un texte. Plus précisément, on cherche la place de la première
apparition du mot W dans le texte T.
Soit n, m deux entiers naturels non nuls, T une chaı̂ne de n caractères et W une chaı̂ne de m caractères,
on suppose que m 6 n.
L’algorithme suivant permet de déterminer l’indice du début de la première apparition de W dans T
Algorithme 3 : Recherche d’une sous-chaine.
Entrées : n et m deux entiers, T (0 : n − 1) et W (0 : m − 1) : deux chaı̂nes de caractères.
Variables : i, j : deux entiers
Début
i←0
x ← −1
Tant que i < n − m + 1 faire
j←0
Tant que j < m et T (i + j) = W (j) faire
j ←j+1
Si j = m alors
x←i
i←n−m+1
sinon
i←i+1
Sorties : La valeur de x, (la valeur −1 signifiant que la sous-chaine n’est pas présente).
Remarque :
Dans le pire des cas, en prenant T = AAAAA....AAA et W = AAA...AAB :
le nombre de comparaisons est égal à (n − m + 1)m.
3
Traduction en une fonction Python :
def recherche_mot(W,T):
"""str,str->int
retourne la position de la première apparition de W dans T """
x=-1
n=len(T)
m=len(W)
i=0
while i<n-m+1:
j=0
while j<m and W[j]==T[i+j]
j=j+1
if j==m:
x=i
i=n-m+1
# Arr^
ete la boucle en i
else:
i=i+1
return x
On peut faire plus simple en Python :
def recherche_mot(W,T):
n=len(T)
m=len(W)
for i in range(n-m+1):
if T[i:i+m]==W:
return i
return None
3) Calcul d’une somme, d’un produit, d’une moyenne..
Un algorithme pour calculer la somme des valeurs dans une liste :
Algorithme 4 : Somme
Entrées : n un entier, L(0 : n − 1) : une liste de nombre réels
Variables : S un réel
Début
S ← L(0)
Pour i allant de 1 à n − 1 faire
S ← S + L(i)
Sorties : La valeur de S
Remarque : n affectations pour calculer une somme.
Traduction en une fonction Python :
def somme(L):
"""List->float or int
L est une liste de flottants ou d’entiers
retourne la somme des valeurs de L"""
S=L[0]
for k in range(1,len(L)):
S=S+L[k]
return S
4
Un algorithme pour calculer le produit des valeurs dans une liste :
Algorithme 5 : Produit
Entrées : n un entier, L(0 : n − 1) : une liste de nombre réels
Variables : P un réel
Début
P ← L(0)
Pour i allant de 1 à n − 1 faire
P ← P ∗ L(i)
Sorties : La valeur de P
Remarque : n affectations pour calculer un produit.
Traduction en une fonction Python :
def produit(L):
"""List->float or int
L est une liste de flottants ou d’entiers
retourne le produit des valeurs de L"""
P=L[0]
for k in range(1,len(L)):
P=P*L[k]
return S
Un algorithme pour calculer la moyenne des valeurs dans une liste :
Algorithme 6 : Moyenne
Entrées : n un entier, L(0 : n − 1) : une liste de nombre réels
Variables : M un réel
Début
M ← L(0)
Pour i allant de 1 à n − 1 faire
M ← M + L(i)
M ← M/n
Sorties : La valeur de M
Remarque : n + 1 affectations pour calculer une moyenne.
Traduction en une fonction Python :
def somme(L):
"""List->float or int
L est une liste de flottants ou d’entiers
retourne la somme des valeurs de L"""
S=L[0]
for k in range(1,len(L)):
S=S+L[k]
return S/len(L)
5
4) Algorithmes de tri.
Soit L une liste de réels.
Les algorithmes suivants permettent de classer les valeurs de cette liste dans l’ordre croissant.
Algorithme 7 : Tri à bulles
Entrées : n un entier, L(0 : n − 1) : une liste de nombre réels
Variables : a : un réel
Début
Pour i allant de 0 à n − 2 faire
Pour j allant de 1 à n − 1 − i faire
Si L(j − 1) > L(j) alors
a ← L(j)
L(j) ← L(j − 1)
L(j − 1) ← a
Sorties : La liste L
Remarque : Le nombre de comparaisons est égale à :
Traduction en une fonction Python :
def tri_bulle(L):
"""list->list
retourne une liste avec les valeurs de L dans l’ordre croissant"""
n=len(L)
for i in range(n-1):
for j in range(1,n-i):
if L[j-1]>L[j]:
a=L[j]
L[j]=L[j-1]
L[j-1]=a
return L
ou encore :
def tri_bulle(L):
n=len(L)
for i in range(n-1):
for j in range(1,n-i):
if L[j-1]>L[j]:
L[j],L[j-1]=L[j-1],L[j]
return L
Un autre tri : le tri par insertion
Algorithme 8 : Tri par insertion
Entrées : n un entier, L(0 : n − 1) : une liste de nombre réels
Variables : x : un réel, j un entier.
Début
Pour i allant de 1 à n − 1 faire
x ← L(i)
j←i
Tant que j > 0 and L(j − 1) > x faire
L(j) ← L(j − 1)
j ←j−1
L(j) ← x
Sorties : La liste L
6
Remarque :
Le nombre maximum de comparaisons est égale à :
Le nombre minimum de comparaisons est égale à :
Traduction en une fonction Python :
def tri_insertion(L):
"""list->list
retourne une liste avec les valeurs de L dans l’ordre croissant"""
n=len(L)
for i in range(1,n):
x=L[i]
j=i
while j>0 and L[j-1]>x:
L[j]=L[j-1]
j=j-1
L[j]=x
return L
5) Calcul de la médiane d’une liste de nombres.
Quelle est la médiane des listes suivantes :
L1=[3,5,7,1,-5,8,6,9,-1] et L2=[5,7,1,-5,8,6,9,-1]
Algorithme 9 : Calcul de la médiane d’une série statistique.
Entrées : n un entier, L(0 : n − 1) : une liste de nombre réels
Variables : a, med : deux réels, m : un entier.
Début
Si n est pair alors
m ← n/2 + 1
sinon
m ← (n + 1)/2
Pour i allant de 0 à m − 1 faire
Pour j allant de 1 à n − 1 − i faire
Si L(j − 1) > L(j) alors
a ← L(j)
L(j) ← L(j − 1)
L(j − 1) ← a
Si n est pair alors
med ← (L(n/2 − 1) + L(n/2))/2
sinon
med ← L((n − 1)/2)
Sorties : La valeur de med
Remarque : Cet algorithme s’appuie sur le tri à bulles, qu’on ne fait que sur la moitié des valeurs.
7
Traduction en une fonction Python :
def mediane(L):
n=len(L)
if n%2==0:
m=n//2+1
else:
m=(n+1)//2
for i in range(m):
for j in range(1,n-i):
if L[j-1]<L[j]:
a=L[j]
L[j]=L[j-1]
L[j-1]=a
if n%2==0:
return (L[n//2-1]+L[n//2])/2.
else:
print(L)
return L[(n-1)//2]
8
Téléchargement