Les algorithmes à connaitre

publicité
IPT 2e année 2016-17
Lycée Victor Hugo
Table des matières
I
Les algorithmes à connaitre
Informatique pour tous
Deuxième année
2016-2017
Utilisation du polycopié : l’objectif de ce polycopié est de vérifier que vous
maitrisez les algorithmes au programme. Attention : ce n’est pas tout le cours
d’informatique. Munissez-vous d’une feuille et d’un sytlo puis commencez par lire
la table des matières. Pour chaque algorithme :
– Donnez-en une description succinte en français. Forcez-vous à l’écrire en toute
lettre.
– Traduisez ce qui vous avez écrit en langage Python.
– Donnez une estimation de la complexité de l’algorithme.
Si vous butez sur une de ces étapes, alors seulement, vous irez lire la partie correspondante.
1
Recherches et calculs dans une liste
1
Recherche d’un élément dans une liste . . . . . . . . . . . .
2
Recherche du minimum dans une liste . . . . . . . . . . . .
3
Calcul de la valeur moyenne et de la variance d’une liste
4
Recherche dichotomique dans une liste triée . . . . . . . .
5
Recherche de motifs dans une chaîne de caractères . . . .
.
.
.
.
.
2
2
2
2
3
4
II Pivot de Gauss
1
Échelonnement du système . . . . . . . . . . . . . . . . . . . . . . . . .
2
Réduction du système . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
Implémentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
5
5
6
III Recherche des zéros d’une application
1
Dichotomie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
Méthode de Newton . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
8
9
IV Intégration numérique
1
Méthode des rectangles . . . . . . . . . . . . . . . . . . . . . . . . . .
2
Méthode des trapèzes . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
10
10
V Résolution d’équation différentielle
1
Équation différentielle d’ordre 1 . . . . . . . . . . . . . . . . . . . . . .
2
Équations différentielles d’ordre 2 . . . . . . . . . . . . . . . . . . . . .
10
10
11
VI Algorithmes de tris
1
Le tri par insertion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
Le tri fusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
Le tri quicksort (ou tri rapide) . . . . . . . . . . . . . . . . . . . . . . .
12
12
12
13
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
IPT 2e année 2016-17
Lycée Victor Hugo
I
Recherches et calculs dans une liste
1
Recherche d’un élément dans une liste
Néanmoins, si dans un sujet de concours de on vous demander de coder la recherche d’un élément dans une liste ce n’est sans doute pas cette méthode qui est
attendue.
Script 1 H
Soit L une liste d’éléments : chaque élément de L peut être accédé par son indice
i ∈ J0, n−1K. Ainsi : L[i] représente l’élément d’indice i. On veut savoir si un objet
x est élément de L. Pour cela, on peut parcourir toute la liste et tester si l’élément
d’indice i est égal à x. Cette algorithme possède une complexité temporelle linéaire.
Voici un exemple de fonction qui renvoie True ou False selon que x appartient ou
non à L. On suppose que L contient au moins 1 élément.
Programmer deux fonctions (itératives et récursives) recherche_occurence
(x,L) et recherche_occurence_rec(x,L) qui renvoient le nombre d’occurences de la valeur x dans une liste L.
2
def appartient_init (a , liste ) :
" fonction bool é enne testant si un é l é ment x est dans
une liste L donn é e "
res = False
for jj in range ( len ( liste ) ) :
if liste [ jj ] == a :
res = True
return res
Recherche du minimum dans une liste
On suppose que les éléments de la liste L obéissent à une relation d’ordre total.
Pour trouver le plus petit élément, l’idée est de créer une variable min_potentiel
correspondant potentiellement au minimum et valant initalement L[0]. Puis, on
parcourt la liste et on modifie min_potentiel à chaque fois qu’on trouve un élément
qui lui est plus petit. Voici un exemple de fonction qui renvoie le plus petit élément
d’une liste ainsi que son indice. On suppose que L contient au moins 1 élément.
def minimum ( L ) :
min_pot = L [0]
ind_pot = 0
for i in range ( len ( L ) ) :
if L [ i ] < min_pot : # on trouv é un é l é ment
plus petit que le minimum potentiel
min_pot = L [ i ]
ind_pot = i
return ( min_pot , ind_pot )
Une version récursive (de complexité linéaire) serait la suivante :
def appartient_rec (x , L ) :
" fonction bool é enne r é cursive testant si un é l é
ment x est dans une liste L donn é e "
n = len ( l )
if n == 0:
return False
# x n ’ est pas dans la liste
Vide
else :
return x == L [0] or appartient_init (x , L [1:])
Script 2 H
Programmer une fonction récursive max_rec(L) qui renvoie le maximum
d’une liste et son indice.
Remarque : La fonction in de Python permet également de savoir si élément
appartient à une liste :
3
Calcul de la valeur moyenne et de la variance d’une liste
Rappels : On considère une liste de N réels x1 , x2 , ..., xN la valeur moyenne m
et la variance sont définies par :
def appartient_bis (x , L ) :
return ( x in L )
2
IPT 2e année 2016-17
Lycée Victor Hugo
– Si x = L[m] on a trouvé x
– Sinon, si x < L[m] alors il faut chercher x entre debut et m.
– Sinon, si x > L[m] alors il faut chercher x entre m et f in.
– On itère ce processus jusqu’à ce que debut = f in
La complexité d’un tel algorithme est logarithmique. Une possibilité de code itératif
est le suivant :
N
1 X
m=
xi
N
N
1 X
et V =
(xi − m)2
N
i=1
i=1
P
2
2
En développant le terme (xi − m) , on montre que V = N1 N
i=1 xi − m.
Voici une façon de calculer la moyenne ( fonction moyenne(L)) et la variance (
fonction variance(L)) d’une liste L donnée en argument.
def re ch er ch e_ di ch o_ it (L ,p , q x ) :
’’’ Recherche par dichotomie dans la liste tri é e L , l
’é l é ment x entre les indices p et q . ’’’
min = p
max = q
while min <= max :
m = ( min + max ) //2
if x == L [ m ] :
return True
elif x < L [ m ] :
max = m -1
else :
min = m +1
return False
def moyenne ( x ) :
somme =0
for i in x :
somme += i
return somme / len ( x )
def variance ( x ) :
xmoy = moyenne ( x )
ecartcarre =[]
for i in x :
ecartcarre . append (( i - xmoy ) **2)
return moyenne ( ecartcarre )
Remarque : le module numpy possède des fonctions mean et var calculant la
moyenne et la variance.
Une possibilité de code récursif est le suivant :
def appartient (x , L ) :
" fonction bool é enne efficace testant si un é l é
ment est dans une liste tri é e par ordre
croissant donn é e "
n = len ( L )
if n == 0:
return False # a n ’ est pas dans la liste
Vide
elif n == 1:
return x == l [0] # si la liste n ’a qu ’ un é l é
ment , on teste si a est cet é l é ment
else :
m = n //2
Script 3 H
Programmer une fonction kurtosis(L) qui renvoie le kurtosis de L, défini
N 1 X xi − m 4
√
par K =
N
V
i=1
4
Recherche dichotomique dans une liste triée
Soit L une liste de nombres triés par ordre croissant. On veut savoir si un nombre
x appartient à cette liste en utilisant le princippe de dichotomie suivant, en notant
L[debut,fin] la sous-liste de L commençant à l’indice debut et fin :
debut + f in
– On calcule m = E(
), le milieu de la sous-liste.
2
3
IPT 2e année 2016-17
Lycée Victor Hugo
if x == l [ m ]:
return True
elif a < l [ m ]:
return appartient (a , l [: m ])
else :
return appartient (a , l [ m +1:])
5
j = 0
while ( j < p ) and ( texte [ i + j ] == motif [ j ]
) :
j += 1
if j == p :
res = True
return Res
Recherche de motifs dans une chaîne de caractères
Script 4 H
Modifier cette algorithme pour compter le nombre d’occurence d’un mot dans
un texte.
Soit deux chaînes de caractères : texte de taille n et motif de taille p < n. On
veut savoir si motif apparaît dans texte. Le façon « naïve »de le faire consiste à
faire glisser le motif le long de texte et de vérifier s’il y a coïncidence caractère
par caractère. Par exemple, on cherche si aime est dans la phrase LVH aime
Python.
II
La méthode du pivot de Gauss permet de résoudre un système linéaire de n
équations et n inconnues.
Un système linéaire de n équations à n inconnues s’écrit sous la forme suivante :

 a1,1 x1 + · · · + a1,n xn = b1
···
(S) :

an,1 x1 + · · · + an,n xn = bn
Première itération :
indices
texte
motif
0
L
a
1
V
i
2
H
m
3
4
a
5
i
6
m
7
e
8
9
P
10
y
11
t
12
h
13
o
14
n
e
Le a de aime n’est pas égal au L de LVH. On décale le motif d’un cran à droite.
Avec, ∀(i, j) ∈ J1, nK :
– ai,j : les coefficients du système (S),
– xi : les inconnues du système (S),
– bj : les seconds membres du système (S).
Le système d’équations linéaires (S) peut se mettre sous écriture matricielle :
Cinquième itération :
indices
texte
motif
0
L
1
V
2
H
3
4
a
a
5
i
i
6
m
m
7
e
e
8
9
P
10
y
11
t
12
h
13
o
Pivot de Gauss
14
n
Toutes les lettres a, i, m et e coïncident, on a trouvé le motif dans le texte. Cette
algorithme possède une compléxité linéaire en n + p.
Voici une façon de traduire cet algorithme en langage Python.

def recherche ( texte , motif ) :
n = len ( texte )
p = len ( motif )
res = False
for i in range (n - p +1) :
avec
a1,1 a1,2
a2,1 a2,2
A=
··· ···
an,1 an,2
(S) ⇔ AX = B

 
· · · a1,n
x1
 x2 
· · · a2,n 
 , X = 
· · ·
··· ··· 
· · · an,n
xn


b1
 b2 

et B = 
· · ·
bn
La résolution du système d’équations (S) par la méthode du pivot de Gauss se
décompose en deux grandes étapes :
4
IPT 2e année 2016-17
Lycée Victor Hugo
(b) On effectue des opérations Li ← Li +λL1 pour i allant de 2 à n de manière
à faire disparaître x1 des équations 2 à n.
1. échelonnement du système (descente),
2. réduction du système (remontée).
2. Deuxième étape : On recommence les étapes (a) et (b) avec les lignes 2 à n et
l’inconnue x2 (on cherche donc un pivot sur la 2ième colonne dans les lignes L2
à Ln ).
Ces deux étapes d’échelonnement et de réduction du système sont réalisées en
effectuant des opérations élémentaires sur les lignes, ce qui correspond à des
opérations sur les équations :
– multiplication d’une ligne par unscalaire non nul (Li ← λLi ) avec λ 6= 0,
– ajout de λLi à Lj Lj ← Lj + λLi avec i 6= j,
– échange de lignes Li ↔ Lj .
3. Étapes suivantes, jusqu’à la (n − 1)ième étape : On recommence le processus
afin d’obtenir une matrice échelonnée (la ième étape consistant à chercher un
pivot sur la ième colonne dans les lignes Li à Ln ).
Chaque opération élémentaire étant inversible par une opération élémentaire (de
même type), le système (S) et tout système (S’) obtenu à partir de (S) à l’aide
d’opérations élémentaires sur les lignes, sont équivalents et admettent donc les
mêmes solutions.
Effectuer des opérations sur les lignes du système (S) revient à effectuer ces
mêmes opérations sur les lignes de la matrice A et du vecteur B. Plutôt que d’effectuer chaque opération élémentaire sur A puis sur B, les opérations seront effectuées
une seule fois sur une matrice que l’on nomme matrice augmentée du système (S).
La matrice augmentée du système (S) est la matrice notée (A|B) :

a1,1 a1,2
a2,1 a2,2
(A|B) = 
··· ···
an,1 an,2
···
···
···
···
À l’issue de ces opérations, on
type :

a01,1
 0


(A|B)0 =  0

· · ·
0
a01,2
a02,2
0
···
0
···
···
···
···
···
a01,n−1
a02,n−1
a03,n−1
···
0

a01,n b01
a02,n b02 


a03,n b03 

· · · · · ·
a0n,n b0n
Cas d’une matrice A non inversible : s’il n’est pas possible de trouver un
pivot (non nul) sur la ième colonne dans les lignes Li à Ln , la matrice A n’est pas
inversible, on interrompt l’algorithme et on retourne un message d’erreur.

a1,n b1
a2,n b2 

· · · · · ·
an,n bn
2
Si la matrice A du système est inversible (système de Cramer) alors le système
(S) AX = B admet donc une unique solution X = A−1 B. Dans le cas contraire,
nous préciserons ce qui permet de repérer que la matrice A n’est pas inversible au
cours du déroulement du programme.
1
aboutit à une matrice augmentée échelonnée du
Réduction du système
1. Par multiplication de chaque ligne Li par
en 1.
1
,
a0i,i
on change la valeur des pivots
2. La dernière ligne donne alors la valeur de xn . On utilise le pivot valant 1 sur
la dernière ligne et la dernière colonne pour éliminer xn des équations L1 à
Ln−1 par des opérations de la forme Li ← Li + λLj .
Échelonnement du système
1. Première étape :
3. La ligne Ln−1 donne alors la valeur de xn−1 . On utilise le pivot valant 1 en
position (n − 1, n − 1) pour éliminer xn−1 des équations L2 à Ln−2 .
(a) On suppose que le premier coefficient de la première ligne est non nul
(a1,1 6= 0, quitte à échanger deux lignes). Ce premier coefficient non nul
s’appelle le premier pivot.
4. On fait de même jusqu’à la ligne L2 .
5
IPT 2e année 2016-17
Lycée Victor Hugo
def Augmentation (A , B ) :
’’’ Fonction qui retourne de la matrice augment é e
M =( A | B ) à partir de :
A : matrice carr é e ( array nxn )
B : vecteur ( array nx1 ) ’’’
n = A . shape [0]
# nombre de lignes de A
nj = A . shape [1]
# nombre de colonnes de A
mi = B . shape [0]
# nombre de lignes de B
mj = B . shape [1]
# nombre de colonnes de B
if ( n == nj and n == mi ) :
M = np . zeros ([ n , n + mj ])
M [: ,0: n ]= A [: ,:]. copy ()
M [: , n : n + mj ]= B [: ,:]. copy ()
return M
else :
print ( " Syst è me non valide " )
À l’issue de ces opérations, on aboutit à une matrice augmentée échelonnée et
réduite du type :

1
 0

(A|B)00 = 
 0
· · ·
0
0
1
0
···
0
···
···
···
···
···
0
0
0
···
0
0
0
0
···
1

b001
b002 

b003 

· · ·
b00n
On peut finalement extraire la matrice A00 et le second membre B 00 de la matrice
augmentée (A|B)00 . La matrice A00 correspondant à l’identité, on a X = B 00 .
3
Implémentation
Afin de coder le plus efficacement possible le pivot de Gauss, il ne faut pas
hésiter à utiliser des fonctions intermédiaires qui exécutent des tâches simples.
(C’est d’ailleurs un principe qu’il faut toujours se forcer à appliquer.)
Manipulation des lignes :
def PivotNonNul (M , i ) :
’’’ Fonction qui retourne le rang du premier pivot
non nul de la colonne i du tableau M et
renvoie un bool é en qui vaut True en cas d ’
existance de pivot non nul et False dans le
cas contraire ’’’
reussi = True
n = M . shape [0]
rg_mp = i # indice du premier pivot
val_mp = M [i , i ] # valeur du premier pivot
while val_mp ==0 and rg_mp <n -1:
rg_mp = rg_mp +1
val_mp = M [i , rg_mp ] # valeur du pivot
if val_mp == 0:
# print ( ’ Le syst è me n \ ’ est pas inversible ’)
reussi = False
return [ rg_mp , reussi ] # rang du premier pivot non
nul pivot / r é ussi
def EchangeLigne (M ,i , j ) :
’’’ Proc é dure qui é change en place , les lignes i
et j du tableau M ’’’
M [i ,:] , M [j ,:]= M [j ,:]. copy () ,M [i ,:]. copy ()
def AjoutLigne (M ,i ,j , a ) :
’’’ Proc é dure qui ajoute en place à la ligne i du
tableau M la ligne j multipli é e par scal . On
suppose que i est diff é rent de j ’’’
M [i ,:]= M [i ,:]. copy () + a * M [j ,:]. copy ()
def MultiplieLigne (M ,i , scal ) :
’’’ Proc é dure qui multiplie en place la ligne i du
tableau M par le scalaire scal . On suppose
que scal est non nul ’’’
M [i ,:]= scal * M [i ,:]. copy ()
Les différentes étapes :
6
IPT 2e année 2016-17
Lycée Victor Hugo
a = - M [ k ][ i ]/ M [ i ][ i ]
AjoutLigne (M ,k ,i , a )
def Echelonnement ( M ) :
""" Fonction / proc é dure qui impl é mente la phase de
descente de la m é thode du pivot de Gauss , en
place . Renvoie un bool é en qui vaut True en cas
de r é ussite et False dans le cas contraire """
n = M . shape [0]
for i in range (0 , n ) : # jusque n pour d é tecter si
le dernier pivot est nul
# place le meilleur pivot partiel de la
colonne i
[p , reussi ]= PivotNonNul (M , i )
if ( reussi == True ) :
EchangeLigne (M ,i , p )
# puis é limine les termes en dessous du pivot
de la colonne i
for j in range ( i +1 , n ) :
a = - M [j , i ]/ M [i , i ]
AjoutLigne (M ,j ,i , a )
return reussi
def ExtraireSolution ( M ) :
’’’ Fonction qui extrait le second membre de la
matrice augment é e M ’’’
n = M . shape [0]
m = M . shape [1] - n
B2 = np . zeros ([ n , m ])
B2 [: ,:]= M [: , n : n + m ]
return B2
La fonction principale :
def Gauss (A , B ) :
’’’R é solution du syst è me lin é aire AX =B , par la m é
thode du pivot de Gauss partiel .
A : matrice carr é e ( array nxn )
B : vecteur des seconds membres ( array nx1 )
sortie : vecteur des inconnues X ( array nx1 ) ’’’
# cr é ation de la matrice augment é e ( A | B )
M = Augmentation (A , B )
# é chelonnement
reussi = Echelonnement ( M )
# Normalisation / r é duction ( ou l ’ inverse )
Normalisation ( M )
Reduction ( M )
# extraction solution
X = ExtraireSolution ( M )
return [X , reussi ]
def Normalisation ( M ) :
’’’ Proc é dure qui normalise les pivots de M ’’’
n = M . shape [0]
for i in range (0 , n ) :
MultiplieLigne (M ,i ,1/ M [i , i ])
def Reduction ( M ) :
’’’R é duit la matrice ’’’
n = M . shape [0]
for i in range (n -1 ,0 , -1) :
# é limine les termes de M au dessus du pivot
de la colonne i
for k in range (i -1 , -1 , -1) :
# Exemple test1
A1 = np . array ([[ -2 ,4 ,1] ,[8 ,2 , -1] ,[2 , -1 ,2]])
B1 = np . array ([[ -18] ,[6] ,[27]])
# solution : 3 , -5 ,8
[ X1 , inversible ]= Gauss ( A1 , B1 )
7
IPT 2e année 2016-17
Lycée Victor Hugo
III
Recherche des zéros d’une application
La borne droite fournit une valeur approchée par excès.
Soit f : [a, b] → R une applications réelle (a > b), continue sur [a, b] et admettant
au moins une valeur c ∈ [a, b] telle que f (c) = 0. On cherche des algorithme donnant
une valeur approchée de c. Ces algorithmes seront surtout utiles lorsqu’on ne peut
pas calculer de valeurs exactes.
1
Cf
f (b)
a
Dichotomie
c1
0
A
b
Le principe
f (a)
Le principe de la dichotomie repose sur :
- le théorème des valeurs intermédiaires :
Si f : [a; b] → R est continue sur le segment [a, b] et si f (a) et f (b) sont de
signes contraires, alors l’équation f (x) = 0 admet au moins une solution dans
l’intervalle [a, b]
- le théorème de la valeur intermédiaire :
Si f : [a; b] → R est continue et strictement monotone sur [a, b] et si f (a) et
f (b) sont de signes contraires, alors l’équation f (x) = 0 admet une et une
seule solution dans l’intervalle [a, b].
B
Difficultés pratiques
Les suites (gn )n∈N et (dn )n∈N obtenues par la méthode de dichotomie convergent
toujours vers un zéro de la fonction f (sous réserve que f soit continue sur [a; b] et
f (a) × f (b) < 0). Mais s’il y a plusieurs zéro sur l’intervalle considéré, on ne sait
pas vers lequel les suites vont converger.
Le seuil d’arrêt peut être difficile à estimer, d’autant que les calculs des valeurs
prises par f sont nécessairement arrondies comme tout calcul avec des flottants.
Pour obtenir des valeurs approchées d’une solution à l’équation f (x) = 0 dans
l’intervalle [a, b], on peut procéder par dichotomie. La fonction f : [a; b] → R
est supposée continue sur l’intervalle [a, b] et f (a) et f (b) sont supposés de signe
contraire.
- on part de l’intervalle [a, b] donc g0 = a et d0 = b (avec a < b)
- à chaque étape, on évalue la fonction f au point milieu de l’intervalle [gn ; dn ]
n
i.e. en m = gn +d
2 ·
Si f (gn ) et f (m) sont de signe contraire, on se place sur l’intervalle [gn ; m] i.e.
gn+1 = gn et dn+1 = m, car il contient une solution de l’équation f (x) = 0.
Sinon f (dn ) et f (m) sont de signe contraire, et on se place sur [m; dn ] i.e.
gn+1 = m et dn+1 = dn .
- on s’arrête quand la précision est satisfaisante.
À chaque étape, la longueur de l’intervalle est divisée par 2. La borne gauche
gn est une valeur approchée par défaut de la solution recherchée c avec
|gn − c| 6 |b − a| × 2−n .
C
Un exemple de programmation
def zero_dicho (f , a , b , p ) :
’’’f fonction continue sur [ a ; b ] avec a < b
f ( a ) et f ( b ) de signes contraires
renvoie une valeur approch é e d ’ une solution de f (
x ) =0 dans [a , b ] à la pr é cision p ’’’
g = a # extr é mit é gauche
d = b # extr é mit é droite
while d - g >= p : # g < d
m = ( g + d ) /2
if f ( m ) * f ( g ) <= 0:
d = m
else :
8
IPT 2e année 2016-17
Lycée Victor Hugo
g = m
return g
2
Méthode de Newton
A
Le principe
On peut réitérer le procédé pour améliorer cette fois la précision de a0 : on obtient
une nouvelle valeur approchée a00 , que l’on peut elle aussi affiner... et ainsi de suite
aussi longtemps qu’on le souhaite. On construit ainsi une suite d’approximations
(an )n∈N de la solution x ∗ qui vérifient :
On cherche à résoudre numériquement une équation de la forme f (x) = 0 où
f est une fonction d’une variable réelle, à valeurs réelles, assez régulière (i.e. au
moins dérivable). On note x ∗ une solution de cette équation que l’on souhaite
approcher.
a0 = a
On part de a, une valeur approchée assez grossière de x ∗ . Pour améliorer sa
précision :
- on trace la tangente à la courbe de f au point a ;
- on repère le point d’intersection de cette tangente avec l’axe des abscisses ;
- l’abscisse a0 de ce point est une nouvelle valeur approchée de x ∗ dont on espère
qu’elle est plus précise que a !
0
x∗
a1
B
f (a0 )
f (an )
f 0 (an )
Exemple de programmation
def Newton (f , fd , x0 , epsilon ) :
’’’ Recherche à espilon pr è s du z é ros de la
fonction f , de d é riv é e fd , proche de x0 ’’’
x = x0
y = x0 - f ( x0 ) / fd ( x0 )
while abs ( y - x ) > epsilon :
x = y
y = x - f ( x ) / fd ( x )
return y
L’équation de la tangente à la courbe au point d’abscisse a est :y = f (a)+f 0 (a) (x−a)
Donc le point d’intersection de cette droite avec l’axe des abscisses a pour coordonnées (a0 , 0) avec : 0 = f (a) + f 0 (a) (a0 − a) d’où :
a0 = a −
∀ n ∈ N, an+1 = an −
• Calcul de la dérivée
Les langages de programmation permettant rarement d’effectuer du calcul formel,
il n’est guère envisageable de calculer automatiquement la dérivée d’une fonction
donnée en un point. Ce problème peut être contourné de plusieurs manières :
- Au cas par cas, on calcule l’expression de la dérivée f 0 à la main puis la code
explicitement dans le programme (on définit la fonction f_prime comme on l’a
fait auparavant pour la fonction f).
- On peut aussi approcher f 0 (a) par un taux d’accroissement :
f (a + h) − f (a)
f 0 (a) '
où h est une constante « petite », fixée à l’avance.
h
Cf
a0
et
f (a)
f 0 (a)
9
IPT 2e année 2016-17
Lycée Victor Hugo
C
La méthode des rectangles approxime
Rb
l’aire a f (x)dx sous la courbe par des rectangles.
Vitesse de convergence
Comparons les performances de la
√ méthode de Newton et de la dichotomie pour
obtenir des valeurs approchées de 2 ' 1.4142135623730951 :
n
0
1
2
3
4
5
6
7
Méthode de Newton
2.0000000000000000
1.5000000000000000
1.4166666666666667
1.4142156862745099
1.4142135623746899
1.4142135623730951
1.4142135623730950
1.4142135623730951
(erreur)
5,9.10−1
8,6.10−2
2,5.10−3
2,1.10−6
1,6.10−12
< 10−16
−2,2.10−16
< 10−16
Méthode par dichotomie
1.0000000000000000
1.5000000000000000
1.2500000000000000
1.3750000000000000
1.4375000000000000
1.4062500000000000
1.4218750000000000
1.4140625000000000
Z
(erreur)
−4,1.10−1
8,6.10−2
−1,6.10−1
−3,9.10−2
2,3.10−2
−8,0.10−3
7,7.10−3
−1,5.10−4
a = a0 a1 a2
Rb
Afin d’approximer
2
a
a
n−1
b−a X
b−a
f (x)dx '
)
f (a + k
n
n
k=0
f à ε près, il faut choisir n tel que : n >
Constante
ε
Méthode des trapèzes
La méthode des trapèzes approxime l’aire
Rb
a f (x)dx sous la courbe Rpar des trapèzes.
b
Elle consiste à approcher a f par :
On constate qu’ici la méthode de √
Newton converge beaucoup plus rapidement
que la méthode par dichotomie, vers 2 : en 5 itérations seulement, on obtient la
précision maximale autorisée par la représentation des flottants en double précision.
Pendant ce temps, la dichotomie n’a produit qu’une seule décimale exacte.
IV
... an−1b = an
b
n−1
a = a0 a1 a2
... an−1b = an
Intégration numérique
Rb
Afin d’approximer
Rb
En général, on ne sait pas calculer la valeur exacte d’une intégrale a f (x)dx. Il
Rb
faut donc trouver des moyens d’approximer a f (x)dx.
Rb
Idée : interpréter a f (x)dx comme l’aire sous la courbe de f , et l’approcher par
l’aire de <<quelque chose>> qu’on sait calculer.
Remarque :
1
1
V
Méthode des rectangles
a
b−aX
(f (ak ) + f (ak+1 ))
2n
k=0
.
q
f à ε près, il faut choisir n tel que : n > Constante
ε
La méthode des trapèzes est plus efficace que celle des rectangles.
Résolution d’équation différentielle
Équation différentielle d’ordre 1
La méthode d’Euler permet de résoudre de manière approchée des équations
différentielles présentées sous la forme
(
y0 (t) = F t, y(t) , t ∈ [t0 , t0 + T ]
y(t0 ) = y0 ,
10
IPT 2e année 2016-17
Lycée Victor Hugo
où F est une fonction de deux variables (t, y), définie au voisinage de (t0 ; y0 ). Ce
cadre permet d’étudier la plupart des équations différentielles du premier ordre sur
un intervalle de temps fini [t0 , t0 + T ], munie d’une condition initiale à l’instant t0 .
Graphiquement, la méthode d’Euler consiste à approcher la courbe (le graphe) de
la fonction solution g, inconnue, par une ligne brisée que l’on construit point après
point (approximation affine par morceaux).
On décompose l’intervalle d’étude en y répartissant n + 1 instants régulièrement
espacés (donc il y a n intervalles de temps) : t0 < t1 < t2 < · · · < tn−1 < tn =
t0 + T .
Deux instants consécutifs sont donc séparés d’un même pas temporel h = Tn
– La valeur de la solution en l’instant t0 est donnée par l’équation : c’est y0 .
On partira donc du point M0 (t0 , y0 )
– Pour construire le point suivant, on utilise l’équation différentielle et on
décide d’assimiler la courbe de y sur l’intervalle [t0 ; t1 ] à sa tangente en t0 :
y(t1 ) = y(t0 ) + (t1 − t0 )F (t0 , y0 ) = y0 + hF (t0 , y0 )
– Et on réitère... jusqu’à arriver à l’instant tn : On approche les valeurs de la
solution aux instants tk par les nombres yk calculés de manière récurrente
par :
∀k ∈ J0, n − 1K, yk+1 = yk + hF (tk , yk )
l’espace des phases (comme en physique lorsque l’on trace un portrait de phase).
Plus précisément, on prend comme inconnues non plus seulement la fonction mais la
fonction et toutes ses dérivées successives jusqu’au l’ordre de l’équation différentielle
moins 1.
Dans le cas d’une équation différentielle
2, d’inconnue y à valeurs réelles
d’ordre
y(t)
~ 0 en fonction de t et
~ (t) =
et d’exprimer u
il suffit d’introduire le vecteur u
y0 (t)
~.
de u
~ (0) = u
~ 0 revient à donner la valeur en t0 de la fonction
La condition initiale u
inconnue y ainsi que de sa dérivée y0 à la même date.
Un pendule libre non amortivérifie
comme équation différentielle θ̈ +
θ
~=
, α représentant la vitesse angulaire
ω02 sin(θ) = 0. Il se traite en posant u
α
θ̇ du pendule. On a alors
Exemple :
~0 =
u
Les points Mk (tk , yk ) dessinent une ligne brisée qui approche la courbe solution sur l’intervalle [t0 , t0 + T ].
~) =
donc ici F~ (t, u
α
−ω02 sin(θ)
La méthode d’Euler s’écrit donc dans ce cas :
(
def euler (T , y0 , t0 , n ) :
y = np . zeros ( n +1)
y [0] = y0
t = t0
for k in range ( n ) :
y [ k +1] = y [ k ] + T / n * F (y , t )
t = t0 + T / n
return y
2
α
θ̇
θ̇
θ̇
=
=
=
−ω02 sin(θ)
α̇
−ω02 sin(θ)
θ̈
θ0 , α0 conditions initiales données et
θk+1 = θk + h αk
αk+1 = αk − ω02 sin(θk )
Ainsi, après application de la méthode d’Euler, on peut facilement tracer θ en
fonction de la date t, mais aussi θ̇ en fonction de θ, i.e. la courbe dans l’espace des
phases.
Un code possible est le suivant :
def euler_pendule (T , omega0 , theta0 , alpha0 , n ) :
h = T/n
thetak , alphak = theta0 , alpha0
theta = [ theta0 ]
alpha = [ alpha0 ]
for k in range ( n ) :
Équations différentielles d’ordre 2
Les équations différentielles d’ordre 2 (ou plus) peuvent se traiter en se réécrivant
sous forme d’un système différentiel vectoriel d’ordre 1. On pourra travailler dans
11
IPT 2e année 2016-17
Lycée Victor Hugo
B
thetakplus1 = thetak + alphak * h
#
attention à ne pas é crire thetak = thetak
+ alphak * h
alphak = alphak - omega0 **2* np . sin ( thetak ) * h
thetak = thetakplus1
theta . append ( thetak )
alpha . append ( alphak )
return ( theta , alpha )
def tri_insertion ( t ) :
n = len ( t )
if n >1:
for k in range (1 , n ) :
a_placer = t [ k ]
j =k -1
a_tester = True # pour ne pas sortir par la
gauche
while a_tester :
if t [ j ] > a_placer :
t [ j +1]= t [ j ]
j =j -1
a_tester = j >=0
else :
a_tester = False
t [ j +1]= a_placer
Remarques : La méthode d’Euler est peu utilisée en pratique car elle est lente et
souvent instable. On lui préfère d’autres méthodes plus sophistiquées, notamment la
méthode du point milieu ou plus généralement les méthodes de Runge-Kutta. Ces
méthodes sont déjà implantées en Python, ainsi que d’autres très performantes : il
suffit de charger la bibliothèque scipy en particulier son module integrate, et
utiliser par exemple la fonction odeint.
VI
1
Algorithmes de tris
Le tri par insertion
Le tri insertion est un algorithme efficace de tri pour un petit nombre d’éléments.
Il est souvent utilisé pour trier un jeu de cartes, un paquet de copies.
A
Algorithme
2
Le tri fusion
A
Le principe
Il s’agit d’utiliser la méthode "diviser pour régner" qui consiste ici à diviser le
tableau en deux parties de même taille (à une unité près si besoin est), de trier
(récursivement) ces deux parties et de fusionner les deux listes sous-triées en une
seule liste triée.
Comme à chaque étape, on diminue strictement la taille du tableau (partie de tableau) à trier, on finit toujours par obtenir un tableau vide ou de longueur 1. Pour
fusionner en une seule liste, on parcourt les deux sous-listes triées (en faisant
attention à ne pas sortir des tableaux) en ajoutant les éléments un à un.
La complexité temporelle de l’algorithme de tri fusion est en O(n ln n) .Il n’y a
pas de meilleur ou de pire des cas.
Le principe
Il consiste à trier la liste élément par élément, de manière à ce qu’à chaque instant
le début de la liste soit triée (la fin de la liste ne servant que pour le stockage).
A la k-ième étape, on suppose que les k premiers éléments de la liste sont bien
dans l’ordre croissant et on insère le (k + 1)-ième élément de la liste à sa place
parmi les éléments déjà triés. Cela peut se faire par échanges successifs avec les
éléments précédents : on échange l’élément à insérer avec celui qui le précède tant
que l’élément à insérer n’est pas bien placé.
La complexité temporelle de l’algorithme du tri par insertion est linéaire dans le
meilleur des cas (liste déjà triée) ou quadratique dans le pire des cas (liste triée à
l’envers). Sa complexité spatialle est quasi nulle.
B
12
Algorithme
IPT 2e année 2016-17
Lycée Victor Hugo
la liste concaténée Li (triée), x, Ls (triée). La complexité temporelle de l’algorithme
de tri rapide est en O(n ln n) dans le meilleur des cas (le pivot sépare la liste en
deux sous liste de même taille) ou quadratique dans le pire des cas (les éléments
sont tous plus grands ou tous plus petits que le pivot).
def tri_fusion ( t ) :
n = len ( t )
if n <2:
return t
else :
moitie = n //2
gche = tri_fusion ( t [: moitie ])
droit = tri_fusion ( t [ moitie :])
# fusion des sous - listes tri é es
g =0 # indice dans liste gche
d =0 # indice dans liste droit
trie =[] # liste fusionn é e
while g +d < n :
if g < moitie and d <n - moitie :
if gche [ g ] < droit [ d ]:
trie . append ( gche [ g ])
g = g +1
else :
trie . append ( droit [ d ])
d = d +1
else :
if g < moitie :
trie . append ( gche [ g ])
g = g +1
else :
trie . append ( droit [ d ])
d = d +1
return trie
3
Le tri quicksort (ou tri rapide)
A
Le principe
B
Algorithme
def tri_rapide ( t ) :
n = len ( t )
if n <2:
return t
else :
x = t [0] # pivot
# fabrication sous - listes
inf =[]
sup =[]
for i in range (1 , n ) :
y=t[i]
if y > x :
sup . append ( y )
else :
inf . append ( y )
# tri des listes et fusion
L_S = tri_rapide ( sup )
L_I = tri_rapide ( inf )
L_I . append ( x )
L_I . extend ( L_S )
return L_I
Script 5 H
Écrire une fonction de tri rapide qui effectue le tri en place, i.e. avec une
complexité spatiale quasi nulle.
Soit une liste à trier. Le tri rapide repose de nouveau sur un principe récursif ;
on choisit un élément x (dit pivot) dans la liste L à trier, on fabrique la liste Li
(sans la trier pour l’instant) des éléments de L inférieurs à x, celle Ls des éléments
strictement supérieurs à x. On trie (récursivement) Li et Ls , la liste triée est alors
13
Téléchargement