You are on page 1of 130

Informatique et algorithmique avec le

logiciel Python en CPGE scientifique


BGYN Arnaud
9 aot 2015

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

Table des matires


1 Cours de premire anne
1
Structures de donnes en Python . . . . . . . . . . . . . . . . . . .
1.1
Nombres . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.1
Nombres en base 10 et base 2 . . . . . . . . . . .
1.1.2
Reprsentation des nombres . . . . . . . . . . . .
1.1.3
Oprations sur les nombres . . . . . . . . . . . . .
1.2
Les boolens et les tests . . . . . . . . . . . . . . . . . . . .
1.3
Listes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.1
Exemples de listes . . . . . . . . . . . . . . . . . .
1.3.2
Listes dfinies par comprhension . . . . . . . .
1.3.3
Indices, longueur et intervalles . . . . . . . . . . .
1.3.4
Oprateurs sur les listes . . . . . . . . . . . . . . .
1.3.5
Modification dune liste . . . . . . . . . . . . . . .
1.3.6
Smantique de pointeur . . . . . . . . . . . . . .
1.3.7
Autres fonctions et oprations pratiques . . . . .
1.4
Chanes de caractres . . . . . . . . . . . . . . . . . . . . .
2
Programmation . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1
Variables et affectations . . . . . . . . . . . . . . . . . . . .
2.2
Les structures conditionnelles . . . . . . . . . . . . . . . .
2.3
Structures itratives . . . . . . . . . . . . . . . . . . . . . .
2.4
Fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.5
Terminaison et correction dun algorithme . . . . . . . . .
2.5.1
Terminaison . . . . . . . . . . . . . . . . . . . . . .
2.5.2
Correction . . . . . . . . . . . . . . . . . . . . . . .
3
Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1
Gnralits . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2
Math . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3
Numpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.1
Manipuler des listes et des matrices . . . . . . . .
3.3.2
Quelques outils dalgbre linaire . . . . . . . . .
3.3.3
Tableaux alatoires . . . . . . . . . . . . . . . . . .
3.3.4
Polynmes . . . . . . . . . . . . . . . . . . . . . .
3.4
Random . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.5
Matplotlib (trac de courbes) . . . . . . . . . . . . . . . . .
3.6
Scipy (calcul scientifique) . . . . . . . . . . . . . . . . . . .
3.7
Autres modules (time, MySQLdb, sqlite3,...) . . . . . . . .
4
Algorithmes de premire anne . . . . . . . . . . . . . . . . . . . .
4.1
Recherche dun lment dans un tableau/liste. . . . . . .
4.2
Recherche nave dun mot dans une chane de caractres
3

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

7
7
7
7
8
9
10
10
10
11
12
13
13
14
14
15
16
16
20
21
22
23
23
24
25
25
26
26
26
32
35
36
38
38
42
45
46
46
47

4
4.3
4.4

5
6

Recherche du maximum dans un tableau/liste de nombres. . . . . . . . .


Calcul de la moyenne, de la variance des valeurs dun tableau/liste de
nombres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.5
Recherche par dichotomie dans un tableau/liste tri . . . . . . . . . . . .
4.6
Recherche par dichotomie dun zro dune fonction continue . . . . . .
4.7
Mthode de Newton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.8
Calcul de valeur approches dintgrales sur un segment par la mthode
des rectangles ou des trapzes . . . . . . . . . . . . . . . . . . . . . . . . .
4.9
Rsolution dune quation diffrentielle ordinaire : mthode ou schma
dEuler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10 Rsolution dun systme linaire inversible : mthode du pivot de Gauss
Lire et crire dans un fichier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Bases de donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.1
Gnralits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2
Requtes simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3
Constructions ensemblistes . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.4
Requtes composes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2 Cours de deuxime anne


1
Piles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1
Gnralits . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2
Primitives . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3
Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
Rcursivit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1
Gnralits . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2
Exemples plus volus . . . . . . . . . . . . . . . . . . . . .
2.3
Pile dexcution dune fonction rcursive . . . . . . . . . .
2.4
Terminaison et correction dune fonction rcursive . . . .
2.5
Complexit dun algorithme rcursif . . . . . . . . . . . .
2.6
Version rcursive des algorithmes vus en premire anne
2.6.1
Recherche dun lment dans une liste trie . . .
2.6.2
Algorithme de dichotomie . . . . . . . . . . . . .
3
Algorithmes de tri . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1
Gnralits sur les algorithmes de tri par comparaisons .
3.2
Tri par insertion (insertion sort) . . . . . . . . . . . . . . .
3.2.1
Prsentation de lalgorithme . . . . . . . . . . . .
3.2.2
Complexit . . . . . . . . . . . . . . . . . . . . . .
3.3
Tri rapide (quick sort) . . . . . . . . . . . . . . . . . . . . .
3.3.1
Prsentation de lalgorithme . . . . . . . . . . . .
3.3.2
Complexit . . . . . . . . . . . . . . . . . . . . . .
3.4
Tri fusion (merge sort) . . . . . . . . . . . . . . . . . . . . .
3.4.1
Prsentation de lalgorithme . . . . . . . . . . . .
3.4.2
Complexit . . . . . . . . . . . . . . . . . . . . . .
3.5
Comparaison empirique des trois algorithmes de tri . . .
3.6
Recherche de la mdiane dans un tableau . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

47
48
48
49
50
51
53
57
61
63
63
64
68
70
73
73
73
74
75
76
76
77
78
79
81
83
83
84
84
84
85
85
86
88
88
91
93
93
96
98
99

3 Exercices de premire anne


101
1
Structure de donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
1.1
Reprsentation des nombres . . . . . . . . . . . . . . . . . . . . . . . . . . 101
1.2
Listes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

2
3

1.3
Chanes de caractres . . . . . . . . . . . . . . . . . . . . . . . .
Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Algorithmique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1
Algorithmique des tableaux/listes et des chanes de caractres
3.2
Mthode dEuler . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3
Algorithme de Gauss-Jordan . . . . . . . . . . . . . . . . . . . .
Lire et crire dans un fichier . . . . . . . . . . . . . . . . . . . . . . . . .
4.1
Requtes SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4 Exercices de seconde anne


1
Piles . . . . . . . . . . . . . . .
2
Rcursivit . . . . . . . . . . .
3
Tris . . . . . . . . . . . . . . .
4
Autres . . . . . . . . . . . . . .
4.1
Stganographie . . . .
4.2
Algorithme de Dijkstra
4.3
quation de la chaleur

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

102
103
103
103
104
106
107
107

.
.
.
.
.
.
.

113
113
115
119
120
120
124
128

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

Chapitre 1
Cours de premire anne
1 Structures de donnes en Python
1.1 Nombres
1.1.1 Nombres en base 10 et base 2
En informatique, linformation est rprsente par des squences de 0 et de 1. Les symboles
0 et 1 sont appels boolens, chiffre binaires, ou encore bit (acronyme de binary digits).
Les nombres que nous manipulons sont habituellement reprsents en base 10 : intuivement, pour dnombrer des objets, on les regroupe en paquets de 10, 100, 1000 etc. . .Par
exemple, 2015 signifie 2 1000 + 0 100 + 1 10 + 5, donc 2 paquets de 1000, aucun paquet
de 100, un paquet de 10 et un reste de 5 units.
En informatique, les nombres sont reprsents en base 2. Il est relativement ais de passer
de la base 10 la base 2, et rciproquement.
Pour passer de la base 10 la base 2. On effectue des divisions euclidienne par 2 du nombre
n reprsent en base 10, tant que le quotient nest pas gal 0. Si les restes successifs sont
nots r 0 , r 1 , . . . , r q alors :
n = r q r q1 . . . r 1 r 0 2

 Exemple. 2014 = 2 1007 + 0


1
1007 = 2 503 +
1
503 = 2 251 +
1
251 = 2 125 +
1
125 = 2 62 +
0
62 = 2 31 +
1
31 = 2 15 +
1
15 = 2 7 +
1
7 = 23+
1
3 = 21+
1
1 = 2 0 +

Donc n = 11111011110 .
Pour passer de la base 2 la base 10. Si en base 2, n = r q r q1 . . . r 1 r 0 2 , alors en base 10 :
n = r q 2q + r q1 2q1 + + r 1 21 + r 0 20
7

 Exemple. Si en base 2, n = 100111010 , alors en base 10 : n = 2 + 2 + 2 + 2 + 2 = 314.


2

1.1.2 Reprsentation des nombres


Les nombres entiers relatifs sont reprsents en Python sur 32 ou 64 bits (cela dpend de
lordinateur sur lequel on travaille !).
Sils sont reprsents sur n bits (avec n = 32 ou 64), on dispose de 2n nombre binaires possibles, et en Python sont reprsents tous les entiers compris entre 2n1 et 2n1 1 (ce qui
fait bien 2n au total).
Si x est un entier compris entre 0 et 2n1 1, on le reprsente par sa reprsentation en base
2. Elle comportera au plus n 1 chiffres, et donc le premier bit du bloc de n bits sera gal 0.

 Exemple. Sur 8 bits, x = 23 est reprsent par sa reprsentation binaire 00010111 , puisque
2

0 23 28 1 = 127.

Si x est un entier compris entre 2n1 et 1, on le reprsente par la reprsentation en base 2


du nombre x + 2n . Ce nombre est compris entre 2n 2n1 = 2n1 et 2n 1. Il ny a donc pas
de conflit avec le cas prcdent et le premier bit est gal 1.

 Exemple. Sur 8 bits, x = 128 est reprsent par 10000000 puisque 2 = 128 x 1,
2

et x + 28 = 128 est reprsent en binaire par 10000000 .

Pour les raisons donnes ci-dessus, le premier bit est appel bit de signe.
Les nombres entiers forment le type int. Lorsquon manipule des nombres trop grand (ie
plus grand que 2n pour une reprsentation sur n bits), on parle de dpassement de capacit.
En Python 2.x, un nouveau type a t cr, appel long (pour long int). En Python 3.x, les
types int et long sont fusionns, on ne peroit donc pas de dpassement de capacit.
Pour les nombres rels, le choix de la reprsentation est beaucoup plus dlicat. On montre
simplement que tout rel x a une unique criture de la forme m 2n avec = 1, m [1, 2[
et n Z .
Ainsi pour stocker x en mmoire il suffire de stocker ,m et n. et n sont des entiers , respectivement appels signe et exposant de x, donc on procde comme ci-dessus (en tant limit
par les dpassements de capacits).
m, appel mantisse, est un nombre rel de lintervalle [1, 2[. On va stocker sa reprsentation
ap
1 a1 a2 a3
2
en binaire qui scrit 1, a1 a2 a3 . . . a p = 0 + 1 + 2 + 3 + + p cest--dire un nombre
2
2
2
2
2
virgule avec le chiffre 1 gauche de la virgule. Comme certains nombres rels ont un nombre
infini de chiffres aprs la virgule, ils ne seront donc pas reprsentables en machine. En pratique, le chiffre gauche de la virgule tant toujours 1, on ne stocke que les chiffres aprs la
virgule.
Plus prcisment on utilise souvent la norme IEEE 754.
Simple prcision. On utilise 32 bits : 1 bit de signe, 8 bits pour lexposant (126 127) et 23
bits de mantisse (avec 1 bit implicite).
Double prcision. On utilise 64 bits : 1 bit de signe, 11 bits pour lexposant (1022 1023)
et 52 bits de mantisse (avec 1 bit implicite).
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

9
Les nombres ainsi reprsents sont appels flottants et forment en Python le type float. Un
nombre entier peut tre du type int ou du type float : 7 est du type int et 7. est du type
float.
B Il faudra prendre garde deux aspects du type float :
1) Certains nombres peuvent avoir une criture dcimale finie mais une criture binaire infinie, cest--dire que ce sont des nombres simples dun point de vue mathmatique et pourtant non reprsentable en machine ! (Ce sont les nombres non dyadiques : tous les irrationnels et certains rationnels)

+
X
1
1
2
+ 4n+3 = 0, 01100110011001100 . . . a une reprsentation biExemple. 0.4 =
4n+2
2
n=0 2
naire infinie, et nest donc pas reprsentable en machine.

2) Il existe un plus petit nombre strictement positif reprsentable en machine, et tout


nombre non nul et infrieur ce nombre sera considr comme nul ! On ne pourra donc
jamais tester lgalit stricte entre deux flottants, mais plutt tester si la diffrence en valeur
absolue entre ces deux flottants est infrieure une constante bien choisie (de lordre 1010
la plupart du temps).
Pour mesurer lespace mmoire on utilise comme unit loctet qui est un bloc de 8 bits. 210 =
1024 octets donnent un kilo-octets (ko), 1024 kilo-octets donnent un mga-octets (Mo) et
1024 mga-octets donnent un giga-octets (Go). Ainsi un flottant sur 32 bits occupe 4 octets
en mmoire, et sur 64 bits il occupe 8 octets.
Remarquer que le passage de lunit au kilo ne se passe pas comme pour les units traditionnelles : 1000 = 103 est remplac par 1024 = 210 .
1.1.3 Oprations sur les nombres
Trois classes essentiellement (entiers, flottants, complexes).
Les complexes scrivent sous la forme a + bj. Le rel b doit tre spcifi, mme si b=1, et
accol la lettre j. Par exemple 1+1j dsigne le complexe 1 + i .
Oprations sur les nombres :

x
x
x
x

+
*
/

y
y
y
y

# somme de deux entiers, rels ou omplexes


# produit de deux entiers, rels ou omplexes
# diffren e de deux entiers, rels ou omplexes
# division entire (quotient de la division eu lidienne)
# s'applique des entiers ou des rels. Appliqu des
# entier, retourne un 'int', sinon un 'float'
x % y # modulo (reste de la division eu lidienne)
x ** y # x puissan e y
abs(x) # valeur absolue
int(x) # partie entire de l' riture d imale (ne orrespond pas
# la partie entire mathmatique si x < 0:
# par exemple int(-2.2)=-2.
x. onjugate() # retourne le onjugu du nombre omplexe x
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

10

x.real
x.imag

# partie relle
# partie imaginaire

1.2 Les boolens et les tests


Les deux lments de la classe des boolens sont True et False (avec les majuscules).
Oprations sur les boolens :

x &
x |
x ^
not

y
y
y
x

ou
x and y
# et
ou
x or y
# ou
# ou ex lusif
# ngation de x

Toute opration valable sur des entiers lest aussi sur les boolens : le calcul se fait en prenant
la valeur 0 pour False, et la valeur 1 pour True.
La plupart du temps, les boolens sont obtenus au moyen de tests. Tests :

x == y
x
x
x
x
x
x
x

< y
> y
<= y
>= y
!= y
in y
is y

#
#
#
#
#
#
#
#
#

galit (la double galit permet de distinguer


syntaxiquement de l'affe tation)
infriorit stri te
supriorit stri te
infriorit large
supriorit large
diffrent (non galit)
appartenan e (pour les listes, ensembles, hanes de aratres)
identit ( omparaison des identifiants de x et y)

1.3 Listes
Une liste permet de manipuler une squence dobjets.

1.3.1 Exemples de listes


Une liste est reprsente entre crochets, et ses lments sont spars par des virgules :

[1, 10, 2, 3, 2, 2
Une liste peut contenir des objets de nimporte-quel type. Par exemple, des chanes de caractres :

['a', 'b', 'toto'


On peut aussi mlanger des objets de types diffrents dans la mme liste :

[1, 'a', 2, 3, 3.14159, True, False, 1


PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

11
On peut mme avoir une liste qui contient une liste :

[1, [2, 3, 'toto'


Une liste peut tre vide :

[
Les lments dune liste peuvent contenir des expressions complexes, faisant appel des
variables ou des fonctions :

a = 2
[(2 + 3) * a, a * 2

1.3.2 Listes dfinies par comprhension


On peut aussi dfinir une liste par comprhension avec la syntaxe :

[ fon tion(x) for x in liste if test(x)


Exemples :

>>> [2*x for x in range(10)


[0, 2, 4, 6, 8, 10, 12, 14, 16, 18
>>> [x for x in range(10) if x>5
[6, 7, 8, 9
>>> [2*x for x in range(10) if x>5
[12, 14, 16, 18
>>> [2*x for x in range(10) if 2*x>5
[6, 8, 10, 12, 14, 16, 18
>>> [x for x in range(10) if x>5 and x<8
[6, 7
>>> [x+1 for x in [2*x for x in range(10)
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19
>>> [2*x for x in [x+1 for x in range(10)
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20
>>> [i*2 for i in range(10)
[0, 2, 4, 6, 8, 10 ,12 ,14 ,16 ,18 ,20
>>> [i for i in range(10) if i % 2 == 0
[0, 2, 4, 6, 8
Plus compliqu, obtenir tous les nombres premiers infrieur ou gaux 50 :

>>> noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)


>>> primes = [x for x in range(2, 50) if x not in noprimes
>>> primes
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

12
1.3.3 Indices, longueur et intervalles
On accde aux lments individuels dune liste en indiquant leur indice entre crochets. La
numrotation des lments commence zro. Par exemple :

>>> a = [1, 7, 5
>>> a[0
1
>>> a[2
5
On peut utiliser des indices ngatifs pour compter partir de la fin de la liste :

>>> a = [1, 7, 5
>>> a[-1
5
>>> a[-3
1
La fonction len donne la longueur dune liste :

>>> liste = [3, 7, 6


>>> len(liste)
3
On peut extraire un sous-ensemble des lments dune liste en spcifiant un intervalle dindices de la faon suivante : liste[min:max. Les indices conservs sont ceux qui sont suprieurs ou gaux min, et infrieurs strictement max :

>>> liste = [1, 4, 1, 5, 9


>>> liste[1:3
[4, 1
>>> liste[2:2
[
min ou max peut tre omis. Dans ce cas, tout se passe comme si min tait 0, et max tait
len(liste) :
>>> liste[2:
[1, 5, 9
>>> liste[:2
[1, 4
>>> liste[:
[1, 4, 1, 5, 9
Les indices ngatifs peuvent tre utiliss dans les intervalles aussi :

>>> liste[:-1
[1, 4, 1, 5
On peut aussi prciser un pas avec linstruction liste[min:max:pas. Par exemple pour
avoir les lments dindices pairs :

>>> liste[::2
[1, 1, 9

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

13
1.3.4 Oprateurs sur les listes
De la mme manire que les chanes, les listes peuvent tre concatnes avec loprateur +,
et multiplies par un entier :

>>> [1, 2 + [2
[1, 2, 2
>>> [1, 2 * 3
[1, 2, 1, 2, 1, 2
On peut comparer deux listes avec loprateur == :

>>> [1, 2 == [2, 3


False
>>> [1, 2 == [1, 2
True

1.3.5 Modification dune liste


On peut affecter une valeur un lment dune liste :

>>> a = [1, 7, 5
>>> a[1 = 0
>>> a
[1, 0, 5
On peut aussi affecter une liste un intervalle :

>>> a = [1, 7, 5
>>> a[0:2 = [2, 3
>>> a
[2, 3, 5
Lors dune affectation un intervalle, il nest pas ncessaire que les listes soient de longueur
identique :

>>> a = [1, 7, 5
>>> a[0:2 = [2, 3, 4
>>> a
[2, 3, 4, 5
>>> a[0:2 = [
>>> a
[4, 5
La mthode append permet dajouter un lment la fin de la liste :

>>> a = [1, 4, 5
>>> a.append(0)
>>> a
[1, 4, 5, 0

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

14
1.3.6 Smantique de pointeur
Laffectation dune liste une variable ne cre pas une copie de la liste. Voici un exemple de
programme qui illustre ce phnomne :

>>>
>>>
>>>
>>>

a = [1, 7, 5
b = a
a[1 = 0
b
[1, 0, 5

On voit que la modification de la liste a affecte aussi la liste b. Cela peut se reprsenter de la
faon suivante dans un tableau dexcution :

a
L1

b
L1

L1
[1, 7, 5
[1, 0, 5

Pour faire une nouvelle copie de la liste, il est ncessaire dutiliser une expression comme
ci-dessous :

>>>
>>>
>>>
>>>

a = [1, 7, 5
b = a[: # b = a + [, ou b = list(a) ou b = [ x for x in a fon tionnent aussi
a[1 = 0
b
[1, 7, 5

Ce qui donne :

a
L1

b
L2

L1
[1, 7, 5

L2
[1, 7, 5
[1, 0, 5

1.3.7 Autres fonctions et oprations pratiques


On peut trier une liste sur place avec la mthode sort :

>>> a = [1, 5, 3, 2
>>> a.sort()
>>> print(a)
[1, 2, 3, 5
Si on souhaite conserver la liste a intacte, et crer une nouvelle liste, on peut utiliser la fonction sorted :

>>> a = [1, 5, 3, 2
>>> b = sorted(a)
>>> print(b)
[1, 2, 3, 5
>>> print(a)
[1, 5, 3, 2
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

15
Lappartenance une liste peut se tester avec loprateur in :

>>> 1 in [3, 4, 5
False
>>> 4 in [3, 4, 5
True
Le minimum et le maximum peuvent se trouver avec les fonctions min et max :

>>> min([3, 1, 4, 1, 5, 9, 2)
1
>>> max([3, 1, 4, 1, 5, 9, 2)
9
del permet de supprimer un lment dune liste :
>>> a = [0, 1, 2, 3, 4
>>> del a[2
>>> a
[0, 1, 3, 4
Notez quon peut faire la mme opration en affectant une liste vide :

>>> a = [0, 1, 2, 3, 4
>>> a[2:3 = [
>>> a
[0, 1, 3, 4

1.4 Chanes de caractres


Les chanes de caractres peuvent se manipuler de manire quasi identique aux listes,
la diffrence prs quil est impossible de modifier une chane de caractres sur place. Par
exemple :

>>> = "bonjour"
>>> [0
b
>>> [0:3
bon
>>> len( )
7
On peut aussi dlimiter une chane de caractres par des apostrophes ' ' ou pas des triples
guillements """ """.
Si on cherche modifier la chane, il se produit des erreurs :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

16

>>> [0 = "B"
Tra eba k (most re ent all last):
File "<stdin>", line 1, in <module>
TypeError: 'str' obje t does not support item assignment
>>> .append("!")
Tra eba k (most re ent all last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' obje t has no attribute 'append'
Mais on peut obtenir un effet similaire en construisant une nouvelle chane :

>>> = "B" + [1:


>>>
Bonjour
Loprateur dappartenance in permet aussi de tester les sous-chanes :

>>> "x" in
False
>>> "Bon" in
True
Attention : in ne fonctionne pas de cette faon pour les listes.

>>> [1, 2 in [1, 2, 3


False
>>> [1, 2 in [[1, 2, 3
True

2 Programmation
2.1 Variables et affectations
En Python , les variables bnficient dun typage dynamique : le type est dtect automatiquement lors de la cration de la variable par affectation. Il nest donc pas ncessaire de
dclarer la variable avant de lutiliser (comme dans la plupart des autres langages).
Laffectation est laction consistant donner une valeur une variable.

a = 2

# affe tation

Laffectation dune valeur une variable se fait avec lgalit. La ligne ci-dessus donne la
valeur 2 la variable a, ceci jusqu la prochaine modification.
Une affectation peut prendre en argument le rsultat dune opration :

a = 2 + 4
Ce calcul peut mme utiliser la variable a elle-mme :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

17

a = a + 4*a*a
Dans ce cas, le calcul du membre de droite est effectu dabord, et ensuite seulement laffectation. Ainsi, le calcul est effectu avec lancienne valeur de a. Il faut en particulier quune
valeur ait dj t attribue a. Par exemple, si a a initialement la valeur 2, la ligne ci-dessus
attribue la valeur 18 a.
Il existe des raccourcis pour certaines oprations de ce type :

a += 2
a -= 1
a *= 3
a /= 2
a %= 3
a **= 4
et .

#
#
#
#
#
#

quivaut
quivaut
quivaut
quivaut
quivaut
quivaut

a
a
a
a
a
a

=
=
=
=
=
=

a
a
a
a
a
a

+ 2
- 1
* 3
/ 2 (en Python 2.7 division entire si possible)
% 3 (reste modulo 3)
** 4 (puissan e)

Pour afficher la valeur dune variable en ligne de commande, il suffit de taper le nom de la
variable aprs linvite de commande :

>>> a = 2
>>> a
2
Faire un affichage du contenu dune variable lors de lexcution dun programme ncessite
la fonction print(), qui affiche une chane de caractres. On peut aussi lutiliser en ligne de
commande :

>>> print(a)
2
Cette fonction ralise une conversion automatique pralable du contenu de la variable en
chane de caractres, car la fonction print() prend toujours en argument une chane de
caractres.
Il est possible deffectuer simultanment plusieurs affectations de variables (de mme type
ou non) :

>>> a, b, = 5, 'bonjour! ', 3.14


# i i a reoit 5, b reoit 'bonjour! ', reoit 3.14
On peut initialiser plusieurs variables avec une mme valeur en utilisant des = successifs.

>>> x = y = z = 1 # initialise les trois variables x,y,z la valeur 1


>>> x, y, z
(1, 1, 1)
>>> a, b = , d = 3, 8
# pose a= =3, et b=d=8
>>> (a, b) = ( , d) = (3, 8)
# idem, mais 'est plus lisible omme a
>>> a, b, , d
(3, 8, 3, 8)
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

18
Laffectation simultane est un bon moyen dchanger le contenu de deux variables :

>>> x, y = 3, 7
>>> x, y = y, x
>>> [x, y
[7, 3

# on donne x la valeur 3, y la valeur 7


# on hange les valeurs de x et y

On peut bien sr effectuer toute permutation sur un nombre quelconque de variables.

>>> a, b, , d, e = 1, 2, 3, 4, 5
>>> a, b, , d, e = b, , d, e, a
>>> a, b, , d, e
(2, 3, 4, 5, 1)

# permutation ir ulaire sur a, b, , d, e

Comme dans toute valuation, lexpression qui suit le signe = est value en premier (donc
avant que la premire des affectations ne soit ralise).

>>> u, v = 2, 3
# i i u reoit 2, et v reoit 3
>>> u, v = v*v, u*u
# gau he de =, lire la squen e 9, 4
>>> u, v
# don ne pas roire qu'on a effe tu u=v=9 puis v=u=81
(9, 4)
Dans un langage qui ne gre pas laffectation simultane, lchange des valeurs de deux variables x et y ncessite une troisime variable temporaire z :

>>> z=x
>>> x=y
>>> y=z
Chaque variable possde un identifiant (ladresse mmoire associe), et un type (la nature
de lobjet stock dans la variable). Lidentifiant change chaque raffectation, le type peut
changer lui-aussi. Les mthodes associes un objet peuvent le modifier sans changement
didentifiant.

type(a)
id(a)

# affi he le type (la lasse) de la variable ou de l'objet


# affi he l'identifiant (l'adresse en mmoire)

Les principaux types (hors modules complmentaires) :

int
float
omplex
bool
list
tuple
str
fun tion

#
#
#
#
#
#
#
#

Entiers, de longueur non borne


Flottants (rels)
Nombres omplexes
Boolens (True / False)
Liste
n-uplets
Chanes de ara tres (string)
Fon tions

Par exemple :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

19

>>> type(87877654)
< lass 'int'>
>>> type(1.22)
< lass 'float'>
>>> type(True)
< lass 'bool'>
>>> type([1,2)
< lass 'list'>
>>> type('ab ')
< lass 'str'>
>>> type(lambda x:x*x)
< lass 'fun tion'>
Il existe dautres types dans des modules spcifiques, en particulier le type array du module
numpy, pour les tableaux et les matrices.
Certains objets dun type donn peuvent tre convertis en un autre type compatible. Conversions de type :

int(x)
# Convertit un objet x en nombre entier.
float(a)
# Convertit l'entier a en rel flottant
omplex(a)
# Convertit l'entier ou le flottant a en omplexe
str(x)
# Convertit l'objet x de type quel onque en
# une hane de ara tres.
list(x)
# Convertit un l'objet x en liste.
tuple(x)
# Convertit un l'objet x en liste.
Par exemple :

>>> int('24')
24
>>> float(2)
2.0
>>> omplex(2)
(2+0j)
>>> str([2,3,1)
'[2, 3, 1'
>>> str(77+2)
'79'
>>> list((1,2,3))
[1, 2, 3
>>> list('ens')
['e', 'n', 's'
>>> tuple('ab ')
('a', 'b', ' ')

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

20

2.2 Les structures conditionnelles


Une seule structure connatre ici :

if test1:
instru tions1
elif test2:
instru tions2
elif test3:
instru tions3
...
else:
instru tions4

Les clauses elif (il peut y en avoir autant quon veut), ainsi que else sont facultatives.
La structure est comprendre comme suit :
Les intru tions1 sont effectues uniquement si le test1 est True
Les instructions instru tions2 sont effectues uniquement si le test1 est False et
le test2 est True
Les instructions instru tions3 sont effectues uniquement si le test1 et le test2
sont False et le test3 est True
...
Les instructions instru tions4 sont effectues dans tous les autres cas restants.
Le mot elif est comprendre comme une abrviation de else if. Ainsi, la structure prcdente est en fait quivalente une imbrication de structures conditionnelles simples :

if test1:
instru tions1
else:
if test2:
instru tions2
else:
if test3:
instru tions3
else:
instru tions4

B Noubliez pas les double-points, et faites attention lindentation !


Les tests peuvent tre remplacs par toute opration fournissant une valeur boolenne. On
peut en particulier combiner plusieurs tests laide des oprations sur les boolens. Par
ailleurs, Python autorise les ingalits doubles (par exemple un test 2 < x < 4).

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

21

2.3 Structures itratives


Il faut distinguer deux types de structures itratives ; celles o le nombre ditration est connu
ds le dbut (itration sur un ensemble fixe de valeurs), et celles o larrt de litration est
dtermine par un test.
La structure itrative for permet ditrer sur un nombre fini de valeurs. Elle sutilise avec
un objet itrable quel quil soit. La boucle est alors rpte pour toute valeur fournie par
litrateur. Lobjet itrable tant fix, le nombre ditrations est connue ds le dpart.
Boucle for, pour un nombre ditrations connu davance :

for i in objet_iterable:
instru tions
# qui peuvent dpendre de i
Par exemple :

for i in [1,2,5:
print(i)
va afficher les 3 valeurs 1, 2 et 5.
Le classique for i = 1 to n (ou similaire) quon trouve dans la plupart des langages se
traduit alors par :

for i in range(1,n+1):
instru tions
Les itrateurs sont des objets grnant des valeurs les unes aprs les autres en les retournant
successivement. On peut utiliser ces valeurs successives grace linstruction for.
Litrateur le plus utile pour nous sera range, numrant des entiers dans un intervalle donn.

range(a,b,p)
range(a,b)
range(b)

# retourne les entiers de a b-1, ave un pas p


# de mme, ave la valeur par dfaut p=1
# de mme, ave la valeur par dfaut a=0

Ainsi, range(b) permet dnumrer les entiers de 0 b-1.


Boucles portant sur des objets itrables :

for i in range(n):
instr

# ex ute l'instru tion instr pour toute valeur de


# i entre 0 et n-1

for i in liste:
instr

# ex ute l'instru tion instr pour toute valeur (non


# n essairement numrique) de i dans la liste liste

for i in haine:
instr

# ex ute l'instru tion instr pour tout ara tre


# i de la hane de ara tre hane.

La boucle while permet dobtenir un arrt de litration par un test. Il sagit en fait plutt
dune condition de continuation, puisquon itre la boucle tant quune certaine condition
est vrifie.
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

22

while ond:
# Bou le while, pour l'arrt des itrations par un test
instru tions
Tant que la condition ond est satisfaite, litration se poursuit.
Remarquez quune boucle for traditionnelle (de 1 n) peut se traduire aussi par une boucle

while :

i = 1
while i <= n:
instru tions
i +=1
B Remarquer que lincrmentation i+=1 nest pas gr automatiquement (contrairement
la boucle for).
En revanche, ce nest pas le cas de la boucle for sur dautres objets itrables : on ne peut pas
systmatiquement avoir recours une boucle while.

2.4 Fonctions
Une fonction est un morceau de programme que lon isole, et quon peut faire dpendre de
paramtres. Cela permet de :
Dgager le coeur mme du programme de toute technique en isolant cette technique
dans des fonctions (clart et lisibilit du code)
Pouvoir rpter une certaine action plusieurs endroits dun mme programme, ou
mme dans des programmes diffrents (en dfinissant des fonctions dans des fichiers
spars quon importe ensuite)
Rendre certains actions plus modulables en les faisant dpendre de paramtres.
Une fonction prend en paramtres un certain nombre de variables ou valeurs et retourne un
objet (ventuellement None), calcul suivant lalgorithme donn dans sa dfinition. Il peut
aussi agir sur les variables ou les priphriques.
La syntaxe gnrale de la dfinition dune fonction est la suivante :

def nom_de_la_fon tion(x,y):


"""Des ription"""
instru tions
return rsultat
La chane de caractres en raw string (cest--dire entre les """) est facultative. Elle permet
de dfinir la description qui sera donne dans la page daide associe cette fonction. Les
instructions sont les diffrents tapes permettant darriver au rsultat. Linstruction spcifique commenant par return permet de retourner la valeur de sortie de la fonction. Si cette
ligne nest pas prsente, la valeur de sortie sera None (pas de sortie). Cela peut tre le cas
pour une fonction dont le but est simplement de faire un affichage.
Voici un exemple :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

23

def tru (x,y):


"""Que peut bien al uler ette fon tion?"""
while x >= y:
x -= y
return x
Par exemple, en ajoutant la ligne print(tru (26,7)) et en excutant le programme, on
obtient la rponse 5.
Si on veut savoir ce que calcule cette fonction, on peut rajouter la ligne help(tru ). Lexcution du programme nous ouvre alors la page daide de la fonction tru :

Help on fun tion tru in module __main__:


tru (x, y)
Que peut bien al uler ette fon tion?
(END)
ce qui en loccurrence ne va pas vous aider beaucoup. Il va falloir faire marcher vos neurones...
Enfin, notons quon peut dcrire une fonction ponctuellement (sans la dfinir globalement)
grce lin- struction lambda :

lambda x: fon tion(x)

# dsigne la fon tion en la variable x dfinie


# par l'expression fon tion(x)

Cela permet par exemple de donner une fonction en paramtre, sans avoir la dfinir globalement par def.
Pour quune fonction donne plusieurs rsultats en sortie, il suffit des les donner dans une
liste :
return [x0 , x1 , ..., xn ]

2.5 Terminaison et correction dun algorithme


2.5.1 Terminaison
Dans un algorithme non rcursif correctement structur, et sans erreur de programmation
(par exemple modification manuelle dun compteur de boucle for), les seules structures pouvant amener une non terminaison dun algorithme sont les boucles while.
On prouve la terminaison dune boucle en exhibant un variant de boucle, cest--dire une
quantit v dfinie en fonction des variables (x1 , ..., xk ) constituant ltat de la machine, et de
n, le nombre de passages effectus dans la boucle et telle que :
v ne prenne que des valeurs entires ;
la valeur de v en entre de boucle soit toujours positive ;
v prenne des valeurs strictement dcroissantes au fur et mesure des passages dans
la boucle. Ainsi, si v n dsigne la valeur de v au n-ime passage dans la boucle, si les
passages n et n + 1 ont lieu, on a v n < v n+1 .
Le principe de descente infini permet alors daffirmer que :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

24
1. Si, pour une boucle donne, on peut exhiber un variant de boucle, alors le nombre de
passages dans la boucle est finie.
2. Si, pour un algorithme donn, on peut exhiber, pour toute boucle de lalgorithme, un
variant de boucle, alors lalgorithme sarrte en temps fini.
B Il faut bien justifier la validit du variant de boucle pour toute valeur possible dentre.
La terminaison assure un arrt thorique de lalgorithme. En pratique, un deuxime paramtre entre en jeu : le temps de rponse. Ce temps de rponse sans tre infini, peut tre trs
grand (certains algorithmes exponentiels peuvent avoir un temps de rponse de lordre de
milliards dannes pour des donnes raisonnablement grandes !). videmment dans ce cas,
mme si lalgorithme sarrte en thorie, cest dassez peu dintrt.
Prenons comme exemple lalgorithme dEuclide qui calcule le PGCD deux entiers relatifs :
1
2
3
4

def eu lide (a ,b ):
while b >0:
a ,b = b ,a %b
return a

La variable |b| est un variant de boucle, ce qui prouve la terminaison de cet algorithme.
2.5.2 Correction
La terminaison dun algorithme nassure pas que le rsultat obtenu est bien le rsultat attendu, cest- -dire que lalgorithme rpond bien la question pose initialement. Ltude
de la validit du rsultat quon obtient fait lobjet de ce paragraphe. On parle de ltude de la
correction de lalgorithme.
Reprenons lexemple de lalgorithme dEuclide. Cet algorithme a pour objet le calcul du pgcd
de a et b. La preuve mathmatique classique de la correction de lalgorithme repose sur la
constatation suivante : si r est le reste de la division euclidienne de a par b, alors a b = b r .
La preuve mathmatique de ce point ne pose pas de problme.
On constate alors que la quantit w = a b prend toujours la mme valeur lentre dune
boucle (correspondant aussi la valeur la sortie de la boucle prcdente). Cest le fait
davoir une valeur constante qui nous assure que la valeur initiale recherche a b, est gale
a b pour les valeurs finales obtenues pour a et b. Or, en sortie de boucle b = 0, donc
a b = a. Ainsi, le pgcd des valeurs initiales de a et b est gal la valeur finale de a.
De faon gnrale, ltude de la correction dun algorithme se fera par la recherche dune
quantit invariante dun passage lautre dans la boucle. On appellera donc invariant de
boucle une quantit w dpendant des variables x1 , . . . , xk en jeu ainsi ventuellement que du
compteur de boucle n, telle que :
la valeur prise par w en entre ditration, ainsi que la valeur quaurait pris w en cas
dentre dans litration suivant la dernire itration effectue, soit constante.
Si le passage initial dans la boucle est index 0 et que la dernire itration effectue
est indexe n 1, lgalit w 0 = w n permet de prouver que lalgorithme retourne bien
la quantit souhaite.
Dans le cas de lalgorithme dEuclide, la quantit w = a b est un invariant de boucle : il
est constant, et la sortie, puisque b = 0, il prend la valeur a. Ainsi, la valeur retourne par
lalgorithme est bien gal a b, pour les valeurs initiales de a et b, passes en paramtres.
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

25

3 Modules
3.1 Gnralits
De nombreuses fonctions sont dfinies dans des modules spcialises ; cela permet de ne
pas encombrer la mmoire de la dfinition de plein de fonctions dont on ne se servira pas.
On peut se contenter de charger (importer) les modules contenant les fonctions utilises (ou
mme selectionner les fonctions quon importe dans chaque module). De cette manire, on
peut dfinir un trs grand nombre de fonctions, sans pour autant alourdir lensemble.
Pour utiliser une fonction fon t dun module mod, il faut importer cette fonction, ou le module entier avant lutilisation de cette fonction. Cela peut se faire de 3 manires.
Import simple du module :

import mod
#Cette instru tion permet de faire savoir l'ordinateur qu'on
#utilise le module mod. On peut alors utilier les fon tions
#de e module en les faisant pr der du prfixe mod (nom du
#module):
mod.fon t()
Lutilisation de prfixes permet dutiliser des fonctions ayant ventuellement mme nom et
se situant dans des modules diffrents. Certains noms de module sont longs, ou seront utiliss trs souvent. On peut, au moment de limport du module, crer un alias, qui permettra
dappeler les fonctions de ce module en donnant comme prfixe lalias au lieu du nom complet :

import mod as al
al.fon t()
Import dune fonction dun module :

from mod import fon t


# Cette instru tion permet d'importer la dfinition de la fon tion
# fon t, qui peut alors tre utilise sans prfixe:
fon t()
# les autres fon tions du module ne peuvent pas tre utilises, mme
# ave le prfixe.
Attention, si une fonction du mme nom existe auparavant (de base dans Python, ou importe prcdem- ment), elle sera crase.
Import de toutes les fonctions dun module :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

26

from mod import *


# Cette instru tion permet d'importer la dfinition de toutes les
# fon tions du module
fon t()
# les autres fon tions du module peuvent tre utilises de mme.
B Attention aussi aux crasements possibles. Par ailleurs, limport est plus long effectuer,
et dune gestion plus lourde, si le module est gros.

3.2 Math
Le module math offre les fonctions et les constantes mathmatiques usuelles, rsumes dans
ce tableau :
Python

math.fa torial(n)
math.fabs(x)
math.exp(x)
math.log(x)
math.log10(x)
math.pow(x, y)
math.sqrt(x)
math.sin(x)
math. os(x)
math.tan(x)
math.asin(x)
math.a os(x)
math.atan(x)
math.pi
math.e

mathmatiques
n!
|x|
r me x
ln(x)
log10 (x)
xy
p
x
sin(x)
cos(x)
tan(x)
arcsin(x)
arccos(x)
arctan(x)

3.3 Numpy
Dans toute la suite on supposera quon a effectu :

import numpy as np
3.3.1 Manipuler des listes et des matrices

numpy propose un type numpy.ndarray qui offre les fonctionnalits des listes de Python,
mais aussi des routines de calcul efficaces. Dans la suite nous appellerons tableau numpy
toute instance du type numpy.ndarray (ou plus simplement tableau ). Attention : contrairement aux listes, les lments dun tableau numpy doivent tous tre de mme type.
Cration de tableaux monodimensionnels
La fonction np.array transforme une liste Python en tableau numpy :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

27

>>> u = [1, 4, 6, 2
>>> type (u)
<type 'list'>
>>> t = np.array (u)
>>> t
array([1, 4, 6, 2)
>>> type (t)
<type 'numpy.ndarray'>
La fonction np.zeros cre un tableau compos uniquement de zros, le nombre dlments
tant pass en paramtre. Par dfaut les lments sont de type float mais on peut le modifier avec le paramtre facultatif dtype.

>>> np.zeros(5)
array([ 0., 0., 0., 0., 0.)
>>> np.zeros(5, dtype = int)
array([0, 0, 0, 0, 0)
La fonction np.ones fonctionne de la mme manire que np.zeros sauf que les lments
sont tous gaux 1.

>>> np.ones(3, dtype=int)


array([1, 1, 1)
>>> 6*np.ones(4)
array([ 6., 6., 6., 6.)
La fonction np.arange(debut,fin,pas) fonctionne comme range mais renvoie un objet
de type array :

>>> x=np.arange(0,1,0.3)
>>> x
array([ 0., 0.3,

0.6,

0.9)

Cration de tableaux bidimensionnels


La fonction np.array permet de transformer une matrice Python en tableau bidimensionnel numpy :

>>> np.array([[1, 2, [3, 4)


array([[1, 2,
[3, 4)
Les fonctions np.zeros et np.ones fonctionnent de faon similaire au cas monodimensionnel, en renvoyant une matrice quand le paramtre est un couple dentiers. Attention la
double paire de parenthses.

>>> np.zeros ((2,4))


array([[ 0., 0., 0., 0.,
[ 0., 0., 0., 0.)
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

28
La fonction np.eye prend en paramtre un seul entier, et renvoie la matrice identit : les
coefficients de la diagoanle principale sont gaux 1, les autres 0.

>>> np.eye(3)
array([[ 1., 0., 0.,
[ 0., 1., 0.,
[ 0., 0., 1.)
La fonction np.diag prend en paramtre une liste [t0 , . . . , tn1 ] (ou un tableau numpy) et renvoie la matrice diagonale ayant les lments ti sur la diagonale et des zros ailleurs :

>>> np.diag([5, 7,
array([[5,
[0,
[0,

2)
0, 0,
7, 0,
0, 2)

Accs un lment
Accs un lment dun tableau monodimensionnel :

>>> t=np.array([3,7,1)
>>> t[2
1
>>> t[-1=20
>>> t
array([ 3, 7, 20)
Accs un lment dun tableau bidimensionnel :

>>> m = np.array([[3, 8, 1, [2, 7, 3)


>>> m[1 # ligne 1
array([2, 7, 3)
>>> m[1,2 = 50 # ligne 1 olonne 2
>>> m
array([[ 3, 8, 1,
[ 2, 7, 50)
Oprateurs vectorialiss
Chaque fonction mathmatique usuelle possde une fonction numpy qui lui est homonyme
et qui calcule la mme chose sur les objets de type float. Par exemple il existe math.sin et
np.sin. Lavantage des fonctions numpy, cest que si a est un tableau a = array([a0 , . . . , an1 ]),
lappel f(a) renvoie le tableau array[f(a0 ), . . . , f(an1 )]. Ce mcanisme sapplique aussi aux
matrices. Exemple :

>>> x=np.array([3,4)
>>> np.exp(x)
array([ 20.08553692, 54.59815003)
>>> import math
>>> math.exp(x)
TypeError: only length-1 arrays an be onverted to Python s alars
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

29
Lorsque la fonction f ne dispose pas dquivalent numpy (par exemple si elle a t cre par
lutilisateur), on peut la vectorialiser grce linstruction np.ve torize(f). Exemple :

>>> x=np.array([3,4)
>>> np.ve torize(bin)(x)
array(['0b11', '0b100',
dtype='|S5')
Quand les paramtres sont des tableaux numpy, les oprations usuelles (+, , , /, ) effectuent les oprations coefficient par coefficient.

>>> a = np.array([[1, 2, [3, 4)


>>> b = np.eye(2)
>>> a
array([[1, 2,
[3, 4)
>>> b
array([[ 1., 0.,
[ 0., 1.)
>>> a+b
array([[ 2., 2.,
[ 3., 5.)
>>> a-b
array([[ 0., 2.,
[ 3., 3.)
>>> a*b
array([[ 1., 0.,
[ 0., 4.)
>>> a/b
__main__:1: RuntimeWarning: divide by zero en ountered in divide
array([[ 1., inf,
[ inf, 4.)
>>> a**2
array([[ 1, 4,
[ 9, 16)
Il est possible aussi deffectuer une opration du type constante + tableau numpy, dans ce cas
lopration se fait coefficient par coefficient. Ceci existe aussi avec les autres oprations.

>>> 3+a
>>> 3*a

array([[4, 5,
[6, 7)
array([[ 3, 6,
[ 9, 12)

Attention aux homonymies doprateurs :


Loprateur + de numpy nest pas du tout le mme que celui des listes Python. Avec
les listes Python cet oprateur effectue une concatnation, avec les tableaux numpy il
sagit dune addition terme terme.
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

30
Les oprateurs , /, de numpy ne correspondent pas du tout aux oprations matricielles mathmatiques. Ils effectuent simplement un produit (ou une division ou une
mise la puissance) coefficient par coefficient. Pour les oprations matricielles mathmatiques, se rfrer cidessous la section quelques outils dalgbre linaire .
Slicing, vues, copies
Il est possible de slectionner une sous-matrice en ne gardant que certaines lignes conscutives et/ou certaines colonnes conscutives.
Un intervalle dindices est dune des formes suivantes :
debut:fin:pas (les indices entre debut inclus et fin exclu, spars par la valeur
pas) ;
debut:fin (tous les indices entre debut inclus et fin exclu) ;
debut: (tous les indices depuis debut inclus) ;
:fin (tous les indices jusqu fin exclu) ;
: (tous les indices) ;
i (seulement lindice i).
La syntaxe matri e[intervalle d'indi es de lignes, intervalle d'indi es de
olonnes permet de crer une sous-matrice correspondant aux lignes et aux colonnes
slectionnes.

>>> m = np.array([[1, 2, 5, 3, [4, 7, 2, 4, [3, 1, 2, 6)


>>> m
array([[1, 2, 5, 3,
[4, 7, 2, 4,
[3, 1, 2, 6)
>>> m[::2,:
# lignes d'indi es pairs
array([[1, 2, 5, 3,
[3, 1, 2, 6)
>>> m[1:,1:3
# lignes 1 et suivantes, olonnes 1 et 2
array([[7, 2,
[1, 2)
>>> m[:,2
# olonne 2
array([5, 2, 2)
Une sous-matrice obtenue ainsi (mthode dite de slicing) sappelle une vue. Les coefficients
ne sont pas recopis, et lindexage se fait selon la gomtrie de la sous-matrice :

>>> a = m[1:, 1:
>>> a
array([[7, 2, 4,
[1, 2, 6)
>>> a[0,0 = 20
>>> m
array([[ 1, 2, 5, 3,
[ 4, 20, 2, 4,
[ 3, 1, 2, 6)
>>> a[:,:2 = np.eye(2)
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

31

>>> a
>>> m

array([[1, 0, 4,
[0, 1, 6)
array([[1, 2, 5, 3,
[4, 1, 0, 4,
[3, 0, 1, 6)

On constate dans lexemple prcdent quune vue peut servir de membre de gauche dune
affectation. Si on veut une duplication des lments dune matrice numpy, on utilise la fonction np. opy :

>>> a = np. opy(m[1:,


>>> a[0, 0 = 20
>>> m
array([[1, 2,
[4, 1,
[3, 0,

1:)
5, 3,
0, 4,
1, 6)

shape, reshape, on atenate


Lattribut shape dun tableau numpy est un n-uplet o n est le nombre dentres du tableau.
Si le tableau est monodimensionnel, lattribut shape est un 1-uplet contenant le nombre
dlments. Si le tableau est bidimensionnel, lattribut shape est un couple (nombre de lignes,
nombre de colonnes).
La mthode reshape renvoie un nouveau tableau, dont la gomtrie est un uplet pass en
paramtre. Le remplissage se fait ligne par ligne (si la matrice de dpart ne possde pas assez
dlments pour la gomtrie passe en paramtre, la mthode reshape rutilise les lments du dbut ; si la matrice de dpart en possde trop la mthode reshape nutilise pas
tous les lments).

>>> import numpy as np


>>> ve teur = np.array([1,5,2,7,3,8)
>>> ve teur.shape
(6,)
>>> matri e = np. on atenate((ve teur, ve teur+1, 2*ve teur))
>>> matri e
array([1, 5, 2, 7, 3, 8, 2, 6, 3, 8, 4, 9, 2, 10, 4, 14, 6, 16)
>>> matri e.shape
(18,)
>>> p = matri e.reshape(2,9)
>>> p
array([[ 1, 5, 2, 7, 3, 8, 2, 6, 3,
[ 8, 4, 9, 2, 10, 4, 14, 6, 16)
>>> p.shape
(2, 9)
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

32
3.3.2 Quelques outils dalgbre linaire
Produit matriciel
Syntaxe de lappel : numpy.dot(matri e A, matri e B)
Valeur de retour : le produit matriciel A.B
B Loprateur * effectue une multiplication terme terme des lments des deux matrices,
et na donc rien voir avec un produit matriciel.
Exemple :

>>> from numpy.linalg import dot


>>> dot([[1,2,[3,4, np.eye(2))
# syntaxe orre te du produit matri iel
array([[1., 2.,
[3., 4.)
>>> [[1,2,[3,4 * np.eye(2)
# Faux (produit terme a terme)
array([[1., 0.,
[0., 4.)
Rang dune matrice
Syntaxe de lappel : numpy.rank(matri e A)
Valeur de retour : le rang de la matrice A
Exemple :

>>> import numpy as np


>>> a=np.arange(15).reshape(3,5)
>>> a
array([[ 0, 1, 2, 3, 4,
[ 5, 6, 7, 8, 9,
[10, 11, 12, 13, 14)
>>> np.rank(a)
2
Inverse dune matrice
Syntaxe de lappel : numpy.linalg.inv(matri e A)
Valeur de retour : A 1 (provoque une erreur si A nest pas inversible).
Exemple :

>>> from numpy.linalg import inv


>>> inv([[1,2,[3,4)
array([[-2. , 1. ,
[ 1.5, -0.5)
Comme dhabitude avec les logiciels de calcul scientifique, il faut dabord savoir si la matrice est inversible pour linverser, ou encore rester critique vis vis du rsultat retourn.
Lexemple suivant est caractristique.
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

33

>>> import numpy as np


>>> a=np.arange(16).reshape(4,4)
>>> a
array([[ 0, 1, 2, 3,
[ 4, 5, 6, 7,
[ 8, 9, 10, 11,
[12, 13, 14, 15)
>>> np.rank(a) # la matri e n'est pas inversible
2
>>> np.linalg.inv(a)
array([[ 9.00719925e+14, -4.50359963e+14,
1.35107989e+15,
[ -2.40191980e+15,
2.70215978e+15,
-2.10167983e+15,
[ 2.10167983e+15, -4.05323966e+15,
1.50119988e+14,
[ -6.00479950e+14,
1.80143985e+15,
6.00479950e+14)

-1.80143985e+15,
1.80143985e+15,
1.80143985e+15,
-1.80143985e+15,

Les valeurs trs grandes laissent tout de mme planer un certain soupon.
Rsolution dun systme de Cramer
Syntaxe de lappel : numpy.linalg.solve(matri e A, ve teur B)
Valeur de retour : le vecteur X solution de AX = B
Exemple, rsolution de

x + 2y = 2
3x + 4y = 8

>>> from numpy.linalg import solve


>>> solve([[1,2,[3,4, [2,8)
array([ 4., -1.)
Il en est de mme que pour linversion de matrice : il faut savoir rester critique.

>>> import numpy as np


>>> a=np.arange(16,dtype=float).reshape(4,4)
>>> a
array([[ 0.,
1.,
2.,
3.,
[ 4.,
5.,
6.,
7.,
[ 8.,
9., 10., 11.,
[ 12., 13., 14., 15.)
>>> b=np.arange(4,dtype=float)
>>> b[1=5
>>> b
array([ 0., 5., 2., 3.)
>>> x=np.linalg.solve(a,b)
>>> np.dot(a,x)
array([ -2.,
2.,
6., 10.)
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

34
Dterminant
Syntaxe de lappel : numpy.linalg.det(matri e A)
Valeur de retour : le dterminant de A, de type float
Exemple :

>>> from numpy.linalg import det


>>> det([[1,2,[3,4)
-2.0000000000000004
Trace
Syntaxe de lappel : numpy.tra e(matri e A)
Valeur de retour : la trace de A
Exemple :

>>> np.tra e([[1,2,[3,4)


5
Puissance dune matrice
Syntaxe de lappel : numpy.linalg.matrix_power(matri e A, entier n)
Valeur de retour : A n
Exemple :

>>> from numpy.linalg import matrix_power


>>> matrix_power([[1,2,[3,4, -2)
array([[ 5.5 , -2.5 ,
[-3.75, 1.75)
Transpose dune matrice
Syntaxe de lappel : numpy.transpose(matri e A)
Valeur de retour : t A
Exemple :

>>> np.transpose([[1,2,[3,4)
array([[1, 3,
[2, 4)
Autre possibilit :

>>> A = np.array([[1,2,[3,4)
>>> A.T
array([[1, 3,
[2, 4)
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

35
Outils de deuxime anne

numpy.linalg.eigvals permet dobtenir les valeurs propres dune matrice.


numpy.linalg.eig permet dobtenir les valeurs propres et les vecteurs propres dune matrice.
Exemple :

>>> import nupy as np


>>> a=np.array([2,4,6,8,float).reshape(2,2)
>>> a
array([[ 2., 4.,
[ 6., 8.)
>>> np.linalg.eigvals(a)
array([ -0.74456265, 10.74456265)
>>> np.linalg.eig(a)
(array([ -0.74456265, 10.74456265), array([[-0.82456484, -0.41597356,
[ 0.56576746, -0.90937671))
Le premier argument reprsente les valeurs propres, tandis que le deuxime retourne la matrice des vecteurs propres en colonne (une colonne est un vecteur propre).
numpy.poly(A) donne le polynme caractristique de la matrice A.

>>> import numpy as np


>>> M=np.array([1,2,3,4).reshape(2,2)
>>> M
array([[1, 2,
[3, 4)
>>> np.poly(M)
array([ 1., -5., -2.)
cest--dire le polynme M (X ) = X 2 5X 2.
3.3.3 Tableaux alatoires
le sous-module numpy.random dfinit un certain nombre de fonctions de gnration alatoire de nombres, suivant la plupart des lois classiques. Nous nen citons que la loi uniforme,
utiliser laide help(numpy.random) pour dcouvrir les autres en cas de besoin. On suppose
numpy.random import sous le nom npr :

npr.randint(a)

# gnre alatoirement un entier de 0 a-1 in lus,


# de faon uniforme
npr.randint(a,b)
# gnre alatoirement un entier de a b-1 in lus,
# de faon uniforme
npr.random(a,b,n)
# gnre un tableau 1 x n d'entiers alatoirement
# hoisis uniformment entre a et b-1
npr.random()
# gnre alatoirement un rel de [0,1[ de faon uniforme
npr.sample(n)
# gnre un array 1 ligne n olonnes rempli alatoirement
# par des rels de [0,1[ hoisis uniformment
npr.sample(tuple)
# de mme pour un tableau multidimentionnel de
# taille dfinie par le tuple

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

36
La fonction binomial permet de simuler une variable alatoire suivant une loi binomiale
de paramtres n et p. Elle permet donc galement de simuler une variable alatoire suivant
une loi de Bernoulli de paramtres p en prenant simplement n = 1. Cette fonction prend un
troisime paramtre optionnel qui correspond, comme pour les fonctions prcdentes, au
nombre de valeurs obtenir.

>>> npr.binomial(10, 0.3, 7)


array([2, 2, 2, 2, 2, 4, 3)
>>> npr.binomial(1, 0.6, 20)
array([0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1,
1, 1, 1, 0, 1, 1, 1, 1)
Les fonctions geometri et poisson fonctionnement de la mme manire pour les lois gomtrique ou de Poisson.

>>> npr.geometri (0.5, 8)


array([1, 1, 3, 1, 3, 2, 5, 1)
>>> npr.poisson(4, 15)
array([5, 2, 3, 4, 6, 0, 5, 3,
1, 5, 1, 5, 9, 4, 6)

3.3.4 Polynmes
Le sous-module numpy.polynomial.polynomial permet de travailler avec des polynmes :

>>> from numpy.polynomial import Polynomial


Pur crer un polynme, il faut lister ses coefficients par ordre de degr croissant. Par exemple,
pour le polynme X 3 + 2X 3 :

>>> p = Polynomial([-3, 2, 0, 1)
On peut alors utiliser cette variable comme une fonction pour calculer, en un point quelconque, la valeur de la fonction polynme associe. Cette fonction peut agir galement sur
un tableau de valeurs, elle calcule alors la valeur de la fonction polynme en chacun des
points indiqus.

>>> p(0)
-3.0
>>> p([1, 2, 3)
array([ 0., 9., 30.)
Lattribut oef donne accs aux coefficients ordonns par degr croissant ; ainsi p. oef[i
correspond au coefficient du terme de degr i . La mthode degree renvoie le degr du polynme alors que roots calcule ses racines.
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

37

>>> p. oef
array([-3., 2., 0., 1.)
>>> p. oef[1
2.0
>>> p.degree()
3
>>> p.roots()
array([-0.5-1.6583124j, -0.5+1.6583124j,
1.0+0.j)
La mthode deriv renvoie un nouveau polynme, driv du polynme initial. Cette mthode prend en argument facultatif un entier positif indiquant le nombre de drivations
effectuer. De la mme manire la mthode integ intgre le polynme, elle prend un paramtre optionnel supplmentaire donnant la constante dintgration utiliser, ce paramtres
peut tre une liste en cas dintgration multiple ; les constantes dintgration non prcises
sont prises gales zro.

>>> p.deriv(). oef


array([ 2., 0., 3.)
>>> p.deriv(2). oef
array([ 0., 6.)
>>> p.deriv(5). oef
array([-0.)
>>> p.integ(). oef
array([ 0. , -3. , 1. , 0. , 0.25)
>>> p.integ(1, 2). oef
# intgrer une fois ave la onstante 2
array([ 2. , -3. , 1. , 0. , 0.25)
>>> p.integ(2, [1, 2). oef
# intgrer deux fois
array([ 2., 1., -1.5, 0.33333333, 0.0.05)
Les oprateurs +, -, * permettent dadditionner, soustraire et multiplier des polynmes. Ils
fonctionnent gale- ment entre un polynme et un scalaire. Loprateur ** permet dlever
un polynme une puissance entire positive.

>>>
>>>
>>>
>>>

a = Polynomial([1, 2, 1)
b = Polynomial([5, 3)
p = 2*a * b + Polynomial([-7, 2)
p. oef
array([ 3., 28., 22., 6.)
>>> (p**2). oef
array([9., 168., 916., 1268., 820., 264., 36.)

Loprateur / permet de diviser un polynme par un scalaire. Pour diviser deux polynmes
il faut utiliser loprateur // qui renvoie le quotient ; loprateur % calcule le reste.

>>> (p / 2). oef


array([ 1.5, 14. , 11. ,3. )
>>> q = p // a
>>> r = p % a
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

38

>>> q. oef
array([ 10., 6.)
>>> r. oef
array([-7., 2.)
>>> (q * a + r). oef
array([ 3., 28., 22., 6.)

3.4 Random
Pour crer un nombre alatoire, on peut aussi utiliser le module random. Exemple :

>>> import random


>>> random.randint(10,20)
#un entier >=10 et <=20
19
>>> a = random.uniform(10,20)
# un flottant entre 10 et 20 (20 est in lu ou non)
>>> a
14.549546974966514
>>> round(a,4)
#arrondir a la 4eme de imale
14.5495
>>> random. hoi e(['beau','laid','waow')
# hoisir dans une liste
'laid'

3.5 Matplotlib (trac de courbes)


Ce module donne un certain nombre doutils graphiques, notamment pour le trac de courbes.
Nous utiliserons plus souvent le sous-module matplotlib.pyplot, que nous supposerons
import sous lalias plt.

plt.plot(L1,L2, label='nom')

# tra e la ligne brise entre les points


# dont les abs isses sont dans la liste L1
# et les ordonnes dans la liste L2
# Le label sert identifier la ourbe
plt.title("titre")
# Dfinit le titre du graphe (affi h en haut)
plt.grid()
# Affi he un grille en pointills pour
# une meilleure lisibilit
plt.legend(lo = ...)
# Affi he une lgende (asso iant haque
# ourbe son label)
# lo peut tre un nombre (1,2,3,4,5,...)
# plaant la lgende un endroit pr is
# lo peut aussi tre plus expli itement:
# 'upper left' et .
plt.savefigure('nom.ext')

# Sauvegarde le graphe dans un fi hier de e nom


# L'extention dfinit le format
# Voir l'aide pour savoir les formats a epts
plt.show()
# Affi hage l' ran de la figure
plt.imshow(T)
# Affi he une image onstitue de points dont

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

39

# les ouleurs sont dfinies par les valeurs du


# tableau T de dimension 3 ( voir omme un
# tableau de pixels RGB)
Tracs de lignes brises et options de tracs
Pour tracer une ligne brise, on donne la liste des abscisses et la liste des ordonnes puis on
effectue le trac. La fonction axis permet de dfinir la fentre dans laquelle est contenue le
graphique. Loption equal permet dobtenir les mmes chelles sur les deux axes. Les tracs
relatifs divers emplois de la fonction plot se superposent. La fonction plt. lf() efface les
tracs contenus dans la fentre graphique.

1
2
3
4
5
6
7

x = [1. , 2.5 , 4.
y = [3. , 1. , 5.
plt . axis ( ' equal ')
plt . plot (x , y)
plt . axis ([ -1. , 5. , -1. , 6.)
plt . grid ()
plt . show ()

La fonction plot admet de nombreuses options de prsentation. Le paramtre olor permet de choisir la couleur ('g' : vert, 'r' : rouge, 'b' : bleu). Pour dfinir le style de la ligne,
on utilise linestyle ('-' : ligne continue, '--' : ligne discontinue, ':' : ligne pointille).
Si on veut marquer les points des listes, on utilise le paramtre marker ('+', '.', 'o', 'v'
donnent diffrents symboles).

6
5

x = [1. , 2.5 , 4.
y = [3. , 1. , 5.
plt . axis ([ -1. , 5. , -1. , 6.)
plt . plot (x , y , olor = 'r ',
linestyle = ': ', marker = 'o ')
5 plt . show ()
1
2
3
4

4
3
2
1
0
1
1

Tracs de fonction
Pour tracer la courbe reprsentative dune fonction, on dfinit une liste dabscisses puis on
construit la liste des ordonnes correspondantes. Lexemple ci-dessous trace la courbe de
x 7 sin x sur [0, 3].
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

40

1
2
3
4
5
6
7

import math
import numpy as np
def f(x ):
return math . sin ( x)

1.0

0.5

0.0

X = np . arange (0 , 3* np .pi ,
0.01)
8 Y = [ f (x ) for x in X
9 plt . plot (X , Y)
10 plt . show ()

0.5

1.0
0

10

Une autre solution consiste utiliser la fonction ve torize du module numpy qui permet de
transformer une fonction scalaire en une fonction capable de travailler avec des tableaux. Il
est cependant beaucoup plus efficace dutiliser directement des fonctions universelles.
1
2
3
4

def f(x ):
return math . sin ( x)
f = np . ve torize ( f)

Il est noter que les oprateurs python (+, -, *, etc.) peuvent sappliquer des tableaux, ils
agissent alors terme terme. Ainsi la fonction f dfinie ci-dessous est une fonction universelle, elle peut travailler aussi bien avec deux scalaires quavec deux tableaux et mme avec
un scalaire et un tableau.
1
2

def f(x , y) :
return np . sqrt (x **2 + y **2)

>>> f(3, 4)
5.0
>>> f(np.array([1, 2, 3), np.array([4, 5, 6))
array([ 4.12310563, 5.38516481, 6.70820393)
>>> f(np.array([1, 2, 3), 4)
array([ 4.12310563, 4.47213595, 5.)

Tracs darcs paramtrs


Dans le cas dun arc paramtr plan, on dfinit dabord la liste des valeurs donnes au paramtre puis on construit la liste des abscisses et des ordonnes correspondantes. On effectue
ensuite le trac.
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

41
1
2
3
4
5
6
7
8
9
10
11
12
13
14

import numpy as np
def x(t ) :
return np . sin (2* t)
def y(t ) :
return np . sin (3* t)

1.0

0.5

0.0

T = np . arange (0 , 2* np .pi ,
0.01)
X = x(T )
Y = y(T )
plt . axis ( ' equal ')
plt . plot (X , Y)
plt . show ()

0.5

1.0

1.0

0.5

0.0

0.5

1.0

Voici un exemple de trac dun arc paramtr de lespace.


1
2
3
4
5
6
7
8
9

from mpl_toolkits . mplot3d


import Axes3D

ax = Axes3D ( plt . figure () )


T = np . arange (0 , 2* np .pi ,
0.01)
X = np . os (T )
Y = np . sin (T )
Z = T
ax . plot (X , Y , T )
plt . show ()

5
4
3
2
1
0
1.0
0.5
1.0

0.0
0.5
0.0

0.5
0.5
1.0

1.0

Trac de surfaces
Pour tracer une surface dquation z = f (x, y), on ralise dabord une grille en (x, y) puis on
calcule les valeurs de z correspondant aux points de cette grille. On fait ensuite le trac avec
la fonction plot_surfa e.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

import numpy as np
from mpl_toolkits . mplot3d
import Axes3D
1.0

ax = Axes3D ( plt . figure () )

0.5

def f(x ,y ) :
return x **2 - y **2

0.0

0.5

X = np . arange ( -1 , 1, 0.02)
Y = np . arange ( -1 , 1, 0.02)
X , Y = np . meshgrid (X , Y )
Z = f(X , Y)
ax . plot_surfa e (X , Y , Z )
plt . show ()

1.0
1.0
0.5
1.0

0.0
0.5
0.0

0.5
0.5

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

1.0

1.0

42
Trac de lignes de niveau
Pour tracer des courbes dquation f (x, y) = k, on fait une grille en x et en y sur laquelle on
calcule les valeurs de f . On emploie ensuite la fonction ontour en mettant dans une liste
les valeurs de k pour lesquelles on veut tracer la courbe dquation f (x, y) = k.
1
2
3
4
5
6
7
8
9
10
11

import numpy as np
def f(x ,y ):
return x **2 + y **2 + x*y

X = np . arange ( -1 , 1, 0.01)
Y = np . arange ( -1 , 1, 0.01)
X , Y = np . meshgrid (X , Y )
Z = f(X , Y)
plt . axis ( ' equal ')
plt . ontour (X , Y , Z ,
[0.1 ,0.4 ,0.5)
12 plt . show ()

0.5

0.0

0.5

1.0

1.0

0.5

0.0

0.5

1.0

3.6 Scipy (calcul scientifique)


Le module s ipy regroupe un certain nombre de fonctions de calcul scientifique (algorithmes classiques de calcul numrique).
Voici les principales fonctions.

s ipy.integrate.quad(f,a,b)
s ipy.optimize.newton(f,a,g)

# intgrale de f de a b
# rsolution d'quation par la mthode de Newton
# initialise au point a
# g doit tre gal f'
s ipy.integrate.odeint(f,y0,T)
# Rsolution de l'ED y'=f(y,t)
# y0 est la valeur initial (t minimal)
# T est un tableau des temps auquels
# al uler les valeurs de y
Rsolution approche dquations
Pour rsoudre une quation du type f (x) = 0 o f est une fonction dune variable relle,
on peut utiliser la fonction fsolve du module s ipy.optimize. Il faut prciser la valeur
initiale x0 de lalgorithme employ par la fonction fsolve. Le rsultat peut dpendre de cette
condition initiale.
1
2
3
4

import s ipy . optimize as resol


def f(x ) :
return x **2 - 2

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

43

>>> resol.fsolve(f, -2.)


array([-1.41421356)
>>> resol.fsolve(f, 2.)
array([ 1.41421356)
Dans le cas dune fonction f valeurs vectorielles, on utilise la fonction root. Par exemple,
x2 y 2 = 1
pour rsoudre le systme non linaire
x + 2y 3 = 0
1
2

def f(v ):
return v [0**2 - v [1**2 - 1, v [0 + 2* v [1 - 3

>>> sol = resol.root(f, [0,0)


>>> sol.su ess
True
>>> sol.x
array([ 1.30940108, 0.84529946)
>>> sol=resol.root(f, [-5,5)
>>> sol.su ess
True
>>> sol.x
array([-3.30940108, 3.15470054)
Calcul approch dintgrales
La fonction quad du module s ipy.integrate permet de calculer des valeurs approches
dintgrales. Elle renvoie une valeur approche de lintgrale ainsi quun majorant de lerreur
commise. Cette fonction peut aussi semployer avec des bornes dintgration gales + ou
.

1
2
3
4
5

import as np
import s ipy . integrate as integr

def f(x ) :
return np . exp (-x )

>>> integr.quad(f, 0, 1)
(0.6321205588285578, 7.017947987503856e-15)
>>> integr.quad(f, 0, np.inf)
(1.0000000000000002, 5.842607038578007e-11)
Rsolution approches dquations diffrentielles
Pour rsoudre une quation diffrentielle x = f (x, t ), on peut utiliser la fonction odeint du
module s ipy.integrate. Cette fonction ncessite une liste de valeurs de t, commenant
en t0 , et une condition initiale x0 . La fonction renvoie des valeurs approches (aux points
contenus dans la liste des valeurs de t) de la solution x de lquation diffrentielle qui vrifie x(t0 ) = x0 . Pour trouver des valeurs approches sur [0, 1] de la solution x (t ) = t x(t ) qui
vrifie x(0) = 1, on peut employer le code suivant.
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

44
1
2
3
4
5
6

import numpy as np
import s ipy . integrate as integr
import matplotlib. pyplot as plt
def f(x , t) :
return t *x

T = np.arange(0, 1.01, 0.01)


X = integr.odeint(f, 1, T)
X[0
array([ 1.)
X[-1
array([ 1.64872143)
plt.plot(T,X)
plt.show()

1.7

1.6

1.5

1.4

1.3

1.2

1.1

1.0
0.0

0.2

0.4

0.6

Si on veut rsoudre, sur [0, 5], le systme diffrentiel


initiale x(0) = 2, y(0) = 1 le code devient le suivant.
1
2

0.8

1.0

x (t ) = x(t ) y(t )
avec la condition
y (t ) = x(t ) y(t )

def f(x , t):


return np . array ([ - x [0 - x [1 , x [0 - x [1)

>>> T = np.arange(0, 5.01, 0.01)


>>> X = integr.odeint(f, np.array([2.,1.), T)
>>> X[0
array([ 2., 1.)
>>> plt.plot(X[ :,0, X[ :,1)
>>> plt.show()
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

45

1.2

1.0

0.8

0.6

0.4

0.2

0.0

0.2
0.5

0.0

0.5

1.0

1.5

2.0

Pour rsoudre une quation diffrentielle scalaire dordre 2 de solution


x, on demandera la
x(t )
rsolution du systme diffrentiel dordre 1 satisfait par X (t ) =
.
x (t )

3.7 Autres modules (time, MySQLdb, sqlite3,...)


Le module time permet daccder lhorloge. On sen servira essentiellement pour mesurer
le temps dexcution dune fonction :

time.time()

# donne une valeur d'horloge orrespondant


# l'instant en ours en se onde.

Cette fonction sera utilise comme suit :

from time import time


debut = time()
instru tions
temps_exe ution = time() - debut
Le module MySQLdb permet deffectuer des requtes dans une base de donnes au format
SQL. La syntaxe est la suivante :

import MySQLdb as sql


Base = sql. onne t(host='***',user='***',passwd='***',db='geographie')
# onnexion au serveur MySQL et la base de donnes
requete='SELECT longitude, latitude, zmax FROM \
ommunes WHERE num_departement <= 95'
Base.query(requete) # ex ution de la requte
resultat = Base.use_result()
res = resultat.fet h_row(maxrows=0) # enregistrement du rsultat
Base. lose()
# fermeture de la onnexion
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

46
Le rsultat de la requte est contenu dans la variable res qui est un tuple de tuples : chaque
ligne de rponse de la requte est donne par un tuple ; un tuple contient toutes les rponses.
On peut parcourir les rponses avec une boucle for :

for ligne in res:


print res
Le module sqlite3 permet lui deffectuer des requtes dans une base de donnes au format
SQLite3. La syntaxe est la suivante :

import sqlite3 as lite


onne tion = lite. onne t('base.db')
# re un objet de onnexion vers la base base.db
ur = onne tion. ursor()
# re un urseur qui permettra des modifi ations de la base
ur.exe ute("requte SQL")
# Ex ute l'instru tion donne, dans la syntaxe SQL,
# dans la base pointe par le urseur
res= ur.fet hall()
# enregistre le rsultat
Le rsultat de la requte est contenu dans la variable res qui est une liste de tuples : chaque
ligne de rponse de la requte est donne par un tuple ; une liste contient toutes les rponses.
On peut parcourir les rponses avec une boucle for :

for ligne in res:


print res

4 Algorithmes de premire anne


4.1 Recherche dun lment dans un tableau/liste.
Pour rechercher un lment x dans une liste t, lide est de parcourir t de gauche droite,
jusqu obtenir llment x. En sortie on donne le premier indice i tel que t[i=x, sil existe,
et sinon la fonction renvoie False.
1
2
3
4
5
6
7
8
9

def re her he (t ,x ):
n= len (t)
i =0
while i < n and t[ i != x : # valuation paresseuse de and
i +=1
if i < n:
return i
else :
print False

Si on sautorise les sorties de boucle avec linstruction return, on peut utiliser une boucle
for :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

47
1
2
3
4
5
6

def re her he (t ,x ):
n= len (t)
for i in range (n ):
if t [i == x:
return i # on arr te l ' algorithme
return False # ette ligne n ' est atteinte que si x n '
appartient pas t

Pour valuer les performances de cet algorithme, notons cn le nombre de tests effectus pour
une liste t de taille n. Il est clair que cn = 1 dans le meilleur des cas (t[0=x), et que cn = n
dans le pire des cas (x est le dernier lment).

4.2 Recherche nave dun mot dans une chane de caractres


Lide est la mme que dans lalgorithme prcdent : on parcourt la chane haine de gauche
droite, en testant chaque fois si le mot mot est trouv. Si cest le cas, on renvoie lindice
du premire caractre de mot dans haine, et False sinon.
1
2
3
4
5
6
7
8
9
10
11
12
13

def re her he2( haine , mot ):


n= len ( haine )
p= len ( mot )
if p > n:
return False # mot trop long pour haine
else :
i =0
while i +p <n +1 and haine [ i:i +p != mot : # valuation
paresseuse de and
i +=1
if i +p == n +1:
return False
else :
return i

Avec une boucle for quon peut quitter avec return :


1
2
3
4
5
6
7
8
9
10
11

def re her he2( haine , mot ):


n= len ( haine )
p= len ( mot )
if p > n:
return False # mot trop long pour haine
else :
for i in range (n - p +1) :
if haine [i :i +p == mot :
return i # provoque une sortie de bou le
else :
return False

4.3 Recherche du maximum dans un tableau/liste de nombres.


On parcourt une fois la liste tableau de gauche droite, en mmorisant le plus grand lment rencontr dans une variable auxiliaire maxi. la fin, la variable maxi est gale au plus
grand lment de la liste.
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

48

def maximum ( t):


maxi = t [0
n= len (t)
for k in range (n ):
if t [k> maxi : # le k -i me plus grand l ment est plus
grand que les k -1 premiers
6
maxi = t[k # il devient le nouveau maximum
7
return maxi
1
2
3
4
5

Pour valuer les performances de cet algorithme, notons cn le nombre de tests effectus pour
une liste t de taille n. Il est clair que cn = n dans tous les cas.

4.4 Calcul de la moyenne, de la variance des valeurs dun tableau/liste de


nombres
On rappelle que si t = [t0 , . . . , tn1 ] est un tableau de nombres, sa moyenne est dfinie par :
m=

X
1 n1
tk
n k=0

et sa variance par :
v=
On en dduit les programmes :
1
2
3
4
5
6

X
2
1 n1
tk m
n k=0

def moyenne ( t):


m =0
n= len (t)
for k in range (n ):
m += t [k
return m / float (n ) # Python 2.7

et :
1
2
3
4
5
6
7

def varian e (t) :


v =0
m= moyenne (t )
n= len (t)
for k in range (n ):
v +=( t[k - m) **2
return v / float (n ) # Python 2.7

4.5 Recherche par dichotomie dans un tableau/liste tri


Nous avons dj donn un algorithme de recherche dun lment dans une liste, de complexit dans le pire des cas cn = O (n). Si nous disposons dune liste t trie dans lordre croissant, nous pouvons acclrer la recherche en procdant par dichotomie : on divise le tableau
en deux, on identifie dans quelle partie se trouve llment cherch, puis on recommence
diviser ce sous-tableau en deux et etc. . .
1
2

def re her he_di ho (t ,x ):


n= len (t)

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

49
3
4
5
6
7
8
9
10
11
12
13
14
15

a =0
b=n -1
if t[ a> x or t[b <x : # as triviaux o x n ' est pas dans t
return False
else :
while b -a >0:
# on her he dans t[ a:b
=( a+ b) /2 # Python 2.7
if t[ == x: # x est au milieu
return # on a trouv x !!
elif t[ >x : # x est dans la partie gau he
b = -1
else :
# x est dans la partie droite
a = +1

On peut montrer quaprs k passage dans la boucle, on a ba n/2k . On en dduit


que
dans
le pire des cas, la complexit (en ne comptant que les comparaisons) est cn = O ln(n) . On a
donc nettement amlior les performances de lalgorithme ! Mais il ne faut as perdre de vue
que cette mthode ne fonctionne pas si les donnes ne sont pas pralablement tries. . .

4.6 Recherche par dichotomie dun zro dune fonction continue


On souhaite trouver x [a, b] tel que f (x) = 0, pour une fonction f continue sur [a, b].
Le principe de la dichotomie est dencadrer de plus en plus finement un zro possible, sa prsence tant dtecte par un changement de signe de la fonction, suppose continue (lexistence du zro tant alors assur par le thorme des valeurs intermdiaires) :
On initialise lencadrement par deux valeurs a0 < b 0 telles que f change de signe entre
a0 et b 0 , cest--dire f (a0 ) f (b 0 ) 0.
On coupe lintervalle en deux en son milieu. Puisquil y a changement de signe sur lintervalle, il y a changement de signe sur lune des deux moitis. On conserve la moiti
correspondante.
On continue de la sorte en coupant chauqe tape lintervalle en deux, en gardant la
moiti sur laquelle il y a un changement de signe. On continue jusqu ce que lintervalle obtenu soit de longueur suffisamment petite pour donner une valeur approche
du zro la marge derreur souhaite.
On en dduit le programme python o les arguments dentre sont la fonction f, lintervalle
de recherche [a, b], et la prcision eps :
1
2
3
4
5
6
7
8
9

def di hotomie(f ,a ,b , eps ) :


assert f (a) *f (b) <=0
while b -a > eps :
=( a +b) /2. # Python 2.7
if f (a) *f ( ) <=0:
b=
else :
a=
return b

Par exemple on peut en dduire une approximation de

p
2 la prcision 103 :

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

50

>>> di hotomie(lambda x:x**2-2,0,2,0.001)


1.4150390625
Les points forts de cet algorithme sont : sa simplicit, sa convergence assure, et sa vitesse
raisonnable. Ses points faibles sont : la ncessit dun encadrement pralable du zro, et le
fait que sil y a plusieurs zros dans lintervalle on nen obtient quun. De plus lalgorithme
fait de nombreux appels f ce qui peut ralentir les calculs si la fonction est complexe.

4.7 Mthode de Newton


La mthode de Newton bien plus rapide. On suppose f drivable :
On part dune valeur initiale x0 .
On construit x1 comme lintersection de la tangente en x0 et de laxe des abscisses.
On itre cette construction.
On a alors, pour tout n N :

xn+1 = xn

f (xn )
f (xn )

On arrte lalgorithme ds que la diffrence entre deux termes conscutifs est assez petite.
1
2
3
4
5
6

def newton (f , fprime , x0 , eps ):


u= x0
v=u -f (u) / fprime ( u)
while abs (v -u ) > eps :
u , v = v , v - f(v )/ fprime (v )
return v

Par exemple :

>>> newton(lambda x:x**2-2,lambda x:2*x,1.,0.0001)


1.4142135623746899
B La convergence est extrmement rapide mais cet algorithme est un cauchemar pour linformaticien :
On peut rencontrer des divisions par zro.
La terminaison nest pas assure.
Mme si un rsultat est renvoy, il peut tre loign dun zro de f .
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

51

4.8 Calcul de valeur approches dintgrales sur un segment par la mthode des rectangles ou des trapzes
Le but est de calculer une valeur approche de lintgrale
nue sur un segment [a, b].

Zb
a

f (x) dx dune fonction f conti-

On peut utiliser la mthode des rectangles : on calcule une valeur approche de lintgrale
en ralisant une somme de surfaces de rectangles. Le domaine dintgration est dcoup en
intervalles [xk , xk+1 ] et on fait comme si la fonction restait constante sur chaque intervalle.
Sur chaque intervalle, on ralise ainsi lapproximation suivante :
Zxk+1
xk

f (t ) dt (xk+1 xk ) f (xk )

donc si la subdivision choisie est x0 = a < x1 < < xn = b alors


par :
n1
X
(xk+1 xk ) f (xk )

Zb
a

f (x) dx est approxime

k=0

Dans le cas dune subdivision rgulire, on a xk = a + k

ba
et lapproximation devient :
n

X
ba
b a n1
f a +k
n k=0
n

La mthode des trapzes, comme son nom lindique, consiste remplacer les rectangles par
des trapzes.

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

52

Lapproximation est alors la suivante :


Zb
a

f (x) dx

n1
X
k=0

(xk+1 xk )

f (xk ) + f (xk+1 )
2

et donc dans le cas dune subdivision rgulire :


X
ba
ba
b a n1
f a +k
+ f a + (k + 1)
2n k=0
n
n
Pour viter de nombreux appels f on peut arranger la formule sous cette forme :
"

#
X
b a f (a) + f (b) n1
ba
f a +k
+
n
2
n
k=1
On en dduit les programmes Python :
1
2
3
4
5
6

def re tangles(f ,a ,b ,n) :


""" approximation de l ' int grale de f entre a et b ave n
re tangles """
I =0
for k in range (n ):
I += (b -a ) * f( a +k *(b - a) / float (n) ) / float (n)
#
Python 2.7
return I

et :
1
2
3
4
5
6

def trapezes (f ,a ,b ,n ):
""" approximation de l ' int grale de f entre a et b ave n
trap zes """
I =(b - a) *( f (a ) + f( b) ) /(2.* n )
# Python 2.7
for k in range (1 , n) :
I += (b -a ) * f( a +k *(b - a) / float (n) ) / float (n)
#
Python 2.7
return I

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

53
Intuitivement la prcision sera meilleure pour de grandes valeurs de n. De plus cest la mthode des trapzes qui devrait converger le plus rapidement. On peut le vrifier sur un exemple :

>>> for n in range(20,201,20):


...
print re tangles(lambda x:x**2,0,3,n) , trapezes(lambda x:x**2,0,3,n)
...
8.33625
9.01125
8.6653125
9.0028125
8.77625
9.00125
8.831953125
9.000703125
8.86545
9.00045
8.8878125
9.0003125
8.90380102041 9.00022959184
8.91580078125 9.00017578125
8.92513888889 9.00013888889
8.9326125
9.0001125

4.9 Rsolution dune quation diffrentielle ordinaire : mthode ou schma


dEuler
tant donne une quation diffrentielle crite sous la forme :
x I ,

u (x) = f (x, u(x))

et une initialisation u(x0 ) = y 0 , on souhaite calculer une approximation de la fonction u sur


lintervalle I .
La question initiale qui peut se poser est alors la faon de reprsenter la fonction solution u.
Il serait vain de penser pouvoir en donner une expression par des fonctions usuelles, et une
reprsentation purement numrique ne pourra tre complte (puisquon ne peut renvoyer
quun nombre fini de valeurs). On pourrait distinguer deux situations :
On est intress par une description globale de toute la fonction. Dans ce cas, on peut
choisir un pas p suffisamment petit, et calculer les valeurs de u intervalles rguliers
de pas p. On peut complter ensuite par interpolation linaire (ou reprsenter par un
graphe, qui lui-mme sera trac par interpolation linaire, par exemple sous Python)
On nest intress que par la valeur en un point x. Dans ce cas, on fait de mme quau
point prcdent pour lintervalle [x0 , x], au lieu de lintervalle global. On obtient alors
une valeur approche de u(x) (sans avoir besoin de faire dinterpolation linaire).
Dans les deux cas, lide est la mme : elle consiste progresser par petits pas, et calculer
chaque tape une valeur approche au pas suivant partir des valeurs dj obtenues.
Ainsi, partant dun intervalle [a, b], o a = x0 , on subdivise celui-ci rgulirement en posant
ba
les points intermdiaires xk = a + k
, pour k 0, n. On cherche ensuite des approxin
mations des u(xk ).
Remarquer que le problme de la convergence vers la solution exacte se pose essentiellement pour les valeurs lointaines de x0 . En effet les approximations aux points successifs
tant calcules laide des approximations prcdentes, les erreurs sajoutent de pas en pas :
plus on sloigne de x0 , plus lapproximation obtenue va tre mauvaise.
Comme toujours en analyse numrique, les questions qui se posent sont les suivantes :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

54
Rechercher un algorithme donnant une erreur acceptable, en un temps raisonnable
Contrler prcisment lerreur
Trouver un compris entre temps de calcul et prcision.

La mthode dEuler est base sur une ide trs simple :


Lquation diffrentielle u = f (x, u) et la connaissance de u(x0 ) nous fournissent la
connaissance de u (x0 )
On approche alors localement la courbe de u par sa tangente. Pour un pas suffisamment petit, on peut considrer que cette approximation est valable sur tout lintervalle
[x0 , x1 ].
1 ) de u(x1 ).
On en dduit alors une valeur approche u(x
On fait comme si cette valeur approche tait la valeur exacte : en utilisant lquation
diffrentielle, on en dduit une valeur approche u (x 1) de u (x1 ).
On approche nouveau la courbe de u par sa tangente, elle-mme approche par la
droite calcule laide des valeurs approches calcules de u(x1 ) et u (x1 ). Cest cette
droite qui approche la tangente quon prend comme nouvelle approximation pour le
calcul de u(x2 ).
On continue de la sorte.
La construction est illustre par la figure prcdente. On se rend vite compte quon accumule
les erreurs et que pour des valeurs loignes de x0 , lapproximation risque de ne pas tre trs
bonne.
Conformment aux explications prcdentes, la mthode dEuler consiste donc approcher
k ), calcule par la rcurrence suivante :
u(xk ) par la valeur u k = u(x
u0 = y0
En notant h =
rence :

et

k 0, n 1, u k+1 = f (xk , u k ) (xk+1 xk ) + u k

ba
le pas constant de la subdivision, on peut rcrire la relation de rcurn
k 0, n 1,

u k+1 = h. f (xk , u k ) + u k

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

55
Le code Python est le suivant :
1
2
3
4
5
6
7
8

def Euler (f ,a ,b ,y0 ,n ):


""" r solution appro h e de y '= f (t , y) sur [a ,b ave y (a) = y0
"""
y =[0* n
# initialisation du ve teur y
t =[ a +k* float (b - a) /( n -1) for k in range (n) # initialisation
des piquets de temps
y [0= y0
# ondition initiale
for k in range (1 , n) :
y [k = y[k -1+( b - a) / float (n -1) *f( t[k -1 , y [k -1)
# Python
2.7
return t ,y

En sortie on rcupre le vecteur des piquets de temps, et le vecteur des valeurs approches
de y.
Par exemple appliquons cette mthode pour le problme de Cauchy
valle [0, 5], et comparons la solution approche et la solution exacte.

>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>

y = y
sur lintery(0) = 1

[t,y=EulerTP(lambda t,y:y , 0, 5, 1, 20)


from math import exp
z=[ exp(x) for x in t
import matplotlib.pyplot as plt
plt.plot(t,y,label='Euler')
plt.plot(t,z,label='Exa te')
plt.legend(lo ='upper left')
plt.show()

On voit sur la figure suivante que la solution approche diverge au cours du temps.

Dans certains cas, on peut avoir besoin dutiliser cette mthode pour des fonctions valeurs
vectorielle (cest--dire valeurs dans R2 , R3 . . .). La mthode dEuler est la mme, la fonction
Python est donc la mme mais il faut prendre garde une chose : loprateur + neffectue pas
laddition de deux liste mais leur concatnation !
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

56
Pour utiliser des fonctions vectorielles, il faut donc ne pas utiliser des variables de type list
mais des variables du type array fourni par le module numpy (dans le cas loprateur + correspond bien laddition de deux tableaux).
x1 (t ) = x1 (t ) x2 (t )
x2 (t ) = x1 (t ) x2 (t )
avec la condition initiale x1 (0) = 2, x2 (0) = 1, on considre que la fonction y = (x1 , x2 ) est
solution de y = f (t , y) o f (t , , ) = ( , ). Le code devient le suivant :

Par exemple, si on veut rsoudre sur [0, 5] le systme diffrentiel

1
2
3
4
5
6
7
8
9
10
11
12

import numpy as np

def f(t ,y ):
return np . array ([ - y [0 - y [1 , y [0 - y [1)
def Euler_ve t(f ,a ,b ,y0 ,n ):
y= np . zeros (( n ,2) )
# ette ligne a hang
t =[ a +k* float (b - a) /( n -1) for k in range (n)
y [0= y0
for k in range (1 , n) :
y [k = y[k -1+( b - a) / float (n -1) *f( t[k -1 , y [k -1)
return t ,y

En sortie, le tableau y a deux colonnes : la premire donne les valeurs approches de x1 et la


seconde celles de x2 . Les lignes correspondent aux piquets de temps.

>>>
>>>
>>>
>>>
>>>

import matplotlib.pyplot as plt


[t,y=Euler_ve t(f , 0, 5, np.array([2.,1.), 100)
plt.plot(y[:,0,y[:,1,label='Euler')
plt.legend(lo ='upper left')
plt.show()

On a trac les points (x1 (t ), x2 (t )) en fonction du temps t .

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

57
Le cas des fonctions vectorielles englobe aussi le cas des quations diffrentielles dordre
deux, quon peut ramener lordre un par vectorialisation. Par exemple, considrons lquation x + x = 0 avec les conditions initiales x(0) = 0 et x (0) = 1. La fonction vectorielle
y = (x, x ) vrifie lquation diffrentielle dordre un y = f (t , y) avec f (t , , ) = (, ). On
dfinit en Python la fonction f :
1
2

def f(t ,y ):
return np . array ([ y [1 , -y [0)

Ensuite on utilise la mthode dEuler vectorielle :

>>> [t,y=Euler_ve t(f , 0, 15,

np.array([0.,1.), 400)

En sortie, le tableau y a deux colonnes : la premire donne les valeurs approches de x et la


seconde celles de x . Les lignes correspondent aux piquets de temps.

>>>
>>>
>>>
>>>

import matplotlib.pyplot as plt


plt.plot(t,y[:,0,label='Euler')
plt.legend(lo ='upper left')
plt.show()

On a trace la courbe reprsentative de la fonction t 7 x(t ). On voit que lapproximation


diverge puisque la solution exacte est la fonction sinus, et devrait donc rester entre 1 et 1.

4.10 Rsolution dun systme linaire inversible : mthode du pivot de


Gauss
Les systmes triangulaires sont trs simples rsoudre.

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

58

Ds maintenant, il faut bien comprendre le rle de lquivalence, qui assure que le systme
initial et le systme final ont les mmes solutions.
La rsolution dun systme linaire quelconque passera systmatiquement par une premire
tape pour le mettre sous forme triangulaire en gardant lquivalence avec le systme initial.
Si une quation disparat ou bien fournit une contradiction, alors on peut en conclure
que :
Si lquation 0 = 0 apparat, on peut lliminer du systme en gardant lquivalence.
Si lquation 0 = apparat (avec 6= 0), le systme initial nadmet pas de solution
Pour un systme de Cramer, ces situations ne se prsenteront pas.
La rsolution dun systme triangulaire sera la dernire tape (la plus simple et rapide) de
la rsolution dun systme linaire. On lappelle souvent phase de remonte : on rsout les
quations de bas en haut, en substituant aux inconnues les valeurs trouves dans les lignes
infrieures.
Pour mettre un systme sous forme triangulaire, on va raliser des transvections, cest--dire
des oprations lmentaires de la forme suivante : ajouter tant de fois telle quation telle
autre , afin dliminer une inconnue dans des quations... mais pas dans le dsordre !
On va dcrire ces oprations pour un systme 3 3 dinconnues (x, y, z) dans une situation
favorable, en notant L 1 , L 2 et L 3 les trois quations en jeu. On suppose que le coefficient
en x de la premire quation, appel a, est non nul. On va sen servir comme pivot pour
liminer les autres occurrences de x. Si on note b et c les coefficients en x des deuxime
b
c
et troisime lignes, le systme constitu des quations L 1 , L 2 = L 2 L 1 et L 3 = L 3 L 1
a
a
est alors quivalent au premier et ne fait apparatre x que dans la premire quation. En
supposant que le coefficient en y de la nouvelle deuxime ligne L 2 , appel d , est non nul
(cest alors le nouveau pivot) et en notant e celui de y dans la nouvelle troisime ligne L 3 ,
e
le systme constitu des lignes L 1 , L 2 et L 3 = L 3 L 2 est quivalent au premier systme et
d
triangulaire : on est ramen un cas quon sait traiter.
Lors de la premire tape, on ne touche pas la premire ligne. De mme, la deuxime
tape, on ne touche ni la premire ni la deuxime ligne, et ainsi de suite.
Dans lexemple qui suit, on adopte une notation classique : pour dire quon change la seconde ligne L 2 en L 2 = L 2 + L 1 , on prfrera noter L 2 L 2 + .L 1 . Cela signifie quon appelle dsormais L 2 ce que dsignait auparavant L 2 + L 1 . Aprs cinq oprations de ce type,
on parlera donc toujours de L 8 plutt que de L
8 .

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

59

Dans les cas moins favorables, on peut rencontrer en cours de rsolution dun systme 3 3
ces trois problmes :
Le pivot nest pas l o on veut : si, la premire tape, le coefficient en x de la premire ligne est nul, on peut changer la premire quation avec la deuxime ou la
troisime. De mme, si la seconde tape, le coefficient en y (futur pivot) est nul, on
peut changer la deuxime quation avec la troisime, mais pas la premire (se souvenir quon veut arriver un systme triangulaire : il ne faut pas faire rapparatre x
dans les deux dernires quations).
Il ny a plus de pivot en une variable : si tous les coefficients en x sont nuls (cest rare :
cela revient dire que x napparat pas dans le systme...), on peut prendre y ou z
comme premire variable. De mme, si aprs la premire tape, y napparat ni dans
la deuxime ni dans la troisime quation, on peut prendre z comme deuxime inconnue.
Il ny a plus de pivot : cela signifie que les membres de gauche des quations restantes
sont nuls. Selon que les membres de droite correspondants sont nuls ou pas, ces quations vont disparatre ou bien rendre le systme incompatible.
Les deux dernires situations ne se produiront pas sur un systme de Cramer.
Pour la recherche dun pivot, il faudrait tester la nullit des coefficients sur une colonne. . .mais
tester la nullit dun flottant na pas de sens en informatique ! On prfre donc chercher sur
la colonne en cours le coefficient le plus lev en valeur absolue (ou module). Cela sappelle
la mthode du pivot partiel.
On fait ici lhypothse que le systme initial est de Cramer. Il est important de noter que les
oprations ralises vont introduire des systmes quivalents au premier, qui demeureront
donc des systmes de Cramer.
Comme signal plus haut, on veut liminer des variables dans les quations successives. On
va donc faire en sorte quaprs k tapes, pour tout i entre 1 et k, la i -ime variable ait disparu
de toutes les quations du systme partir de la (i + 1)-ime. Ce sera linvariant de boucle.
Ainsi, aprs la (n 1)-ime tape, le systme sera bien sous forme triangulaire.
Dans le pseudo-code qui suit, on rsout le systme Ax = y. La ligne L i dsigne la fois
les coefficients de A (qui sont dans une matrice, un tableau bidimensionnel) et les seconds
membres, qui sont dans une matrice colonne y. Les indexations de tableaux vont de 0 n 1
comme en Python :
Pour i de 0 n 2 faire
Trouver j entre i et n 1 tel que |a j ,i | soit maximale.
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

60
changer L i et L j (coefficients de la matrice et membres de droite).
Pour k de i + 1 n 1 faire
a
L k L k ak,i L i
i ,i
Fin Pour
Fin Pour
Rechercher j entre i et n tel que |a j ,i | soit maximale (puis changer deux lignes) a deux
objectifs : dune part sassurer que le coefficient en position (i , i ) sera diffrent de 0 (cest
essentiel pour pouvoir pivoter) et, dautre part, minimiser les erreurs numriques dans la
suite du calcul.
Arriv ici, le systme est sous forme triangulaire et il ny a plus qu remonter , via des
substitutions. Le rsultat est mis dans un tableau x et il sagit donc de calculer :
!

n1
X
1
ai ,k xk
yi
xi =
ai ,i
k=i +1
Pour i de n 1 0 faire
Pour k de i + 1 n 1 faire
y i y i ai ,k xk
Fin Pour
y
xi a i
i ,i
Fin Pour
Dans les programmes Python, les matrices seront reprsents par des listes de listes. Par
exemple la matrice 2 3 suivante :

0 1 2
M=
3 4 5
peut tre dfinie en Python par le tableau m ci-aprs :

m = [[0, 1, 2, [3, 4, 5
On accde llment Mi ,j avec lexpression m[i[j.
Comme les listes sont modifies en place, les fonctions ne renverront rien.
Le premier programme Python prend en entre une matrice A et un indice i. Il doit renvoyer
un indice j i tel que |aj,i | soit maximale :
1
2
3
4
5
6
7

def her her_pivot (A , i ):


n = len (A)
# le nombre de lignes
j = i
# la ligne du maximum provisoire
for k in range (i +1 , n ):
if abs (A[ k [ i ) > abs (A [j [ i ) :
j = k
# un nouveau maximum provisoire
return j
# en faisant bien attention l ' indentation : -)

Les changes de lignes se passent de commentaires :


1
2
3
4

def e hange_lignes (A , i , j):


n = len (A [0)
for k in range ( n ):
A [i [ k, A[j [ k = A [j [ k , A[i [ k

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

61
Enfin viennent les transvections. Comme pour la fonction prcdente, la matrice fournie en
entre est modifie en place, la fonction ne renvoyant rien. En particulier, lappel se fera via
transve tion_ligne(A,i,j,mu), et non via A = transve tion_ligne(A,i,j,mu) :
1
2
3
4
5

def transve tion_ligne (A , i , j , mu ):


""" L_i <- L_i + mu . L_j """
n = len (A [0)
# le nombre de olonnes
for k in range ( n ):
A [i [ k += mu * A [j [ k

Il reste recoller les morceaux dans la fonction principale :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

def resolution(A , Y) :
""" R solution de A. X=Y ; A doit etre inversible """
n = len (A)
# Mise sous forme triangulaire
for i in range (n ):
j = her her_pivot (A , i )
if j > i:
e hange_lignes (A , i , j)
e hange_lignes (Y , i , j)
for k in range (i +1 , n):
x = A [k [ i / float (A [i [ i )
transve tion_ligne (A , k , i , -x )
transve tion_ligne (Y , k , i , -x )
# Phase de remont e
X = [0. * n
for i in range (n -1 , -1, -1) :
somme =0.
for j in range (i +1 , n ):
somme += A [i [ j * X [j
X [i = (Y [i [0 - somme ) / A[i [ i
return X

B Les variables A et Y sont modifies en place par la fonction prcdente. Si on souhaite les
garder intactes, il faut en faire une copie ds le dbut du programme. . .
Testons sur un exemple :

>>> resolution([[2,2,-3,[-2,-1,-3,[6,4,4,[[2,[-5,[16)
[-14.000000000000036, 21.000000000000046, 4.000000000000007
Il est clair que la complexit de lalgorithme, en prenant en compte les comparaisons, affectations et oprations arithmtiques, vrifie cn = (n 3 ).

5 Lire et crire dans un fichier


On rassemble ci-dessous les commandes python utiles :
1. Connatre le rpertoire de travail :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

62

>>> import os
>>> os.get wd()
'/home/arno/Dropbox/PSI/Python/Cours_Arnaud'
Changer de rpertoire :

>>> os. hdir('../DM/DM1')


>>> os.get wd()
'/home/arno/Dropbox/PSI/Python/DM/DM1'
2. Ouvrir un fichier : monFi hier=open('adresse du fi hier', 'r')
Le r indique quon ouvre le fichier en lecture ( read ).
Pour louvrir en criture, remplacer par 'w'.
B Attention, ceci crase tout fichier existant ! Si le fichier nexiste pas , il est cr.
Pour ouvrir un fichier en mode ajout de donne , mettre 'a' au lieu de 'w'. De
mme, si le fichier nexiste pas, il est cr.
Remplacez monFi hier par le nom sous lequel vous voulez appeler votre fichier
dans votre programme.
Quand vous avez fini, fermez le fichier grce monFi hier. lose().
3. Lire la ligne courante (si ouvert en mode lecture) monFi hier.readline()
Lors de louverture du fichier, on est au dbut du fichier. chaque utilisation de cette
commande, on passe la ligne suivante.
NB : le type de donne rcupre est toujours du texte. Il faudra ventuellement le
convertir en entier ou flottant.
4. Astuce python : pour parcourir toutes les lignes du fichier vous pouvez utiliser une
boucle pour automatique :

for ligne in monFi hier.readlines():


La variable ligne prendra comme valeurs successives toutes les lignes du fichier.
B Attention au s la fin de readlines.
En fait ceci fonctionne comme pour parcourir une liste (ex : for i in [1,4,7,12,3)
ou une chane de caractre (ex : for lettre in 'bonjour').
5. Rajouter une ligne la fin du fichier (si ouvert en mode criture) :

monFi hier.write(la_ligne__ rire)


Si on veut prciser que la prochaine criture se fera sur un autre ligne, il faut que la
chane de caractres la_ligne__ rire se termine par le caractre fin de ligne
\n.
6. Retirer le caractre fin de la ligne la fin dune chane de caractre : maChaine[:-2
ou maChaine.rstrip('\n')
7. Dcouper une chane de caractre selon les virgules : maChaine.split(',')
Par exemple :

>>> 'ab ,def,f'.split(',')


['ab ', 'def', 'f'
Cette technique fonctionne avec nimporte quel autre caractre que la virgule ,. Par
dfaut le caractre est lespace ' '.
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

63

6 Bases de donnes
6.1 Gnralits
Il sagit de stocker des donnes de faon adapte, de sorte :
pouvoir facilement faire des recherches
prendre le moins de place possible en mmoire.
Un attribut dune base de donne est une des caractristiques dont on souhaite enregistrer
la valeur, lors dune entre. Ainsi, il sagit du nom des diffrentes colonnes.

On reprsente souvent une relation sous forme dune table, comme nous lavons fait prcdemment. Ainsi, le schma relationnel dfinit les noms des colonnes dune table, et le type
des entres de chaque colonne, alors que la relation est lensemble des donnes entres dans
la table. Un enregistrement (ou une valeur) correspond une ligne de la table. Le cardinal de
la relation est le nombre de lignes dans la table.

Une cl primaire est un attibut tel que les valeurs prises par cet attribut dterminent toutes
les autres valeurs de lenregistrement (donc dterminent toute les lignes).

Nous utiliserons dans la suite lexemple suivant de tables.

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

64

De faon naturelle, on peut choisir les cls primaires suivantes :


IDOEUVRE pour la table OEUVRES
IDNAT pour la table NATIONALIT
IDCOMP pour la table COMPOSITEURS
IDSOL pour la table SOLISTES
IDINSTR pour la table INSTRUMENTATION
INSTRUMENT pour la table INSTRUMENT
Nous abordons dans ce cours laspect principal de lutilisation dune base de donne, savoir la rdaction de requtes en langage SQL afin dextraire dune base de donne les informations qui nous intressent. Pour rdiger une requte, il est indispensable de connatre
prcisment la structure de la base (les noms des tables, les noms des attributs, les cls primaires). Ainsi, la premire tape est souvent de rechercher et comprendre cette structure.
Ensuite, les requtes sont toutes effectues laide de linstruction SELECT ... FROM ...
WHERE ...; et de constructions algbriques effectues sur les tables, en particulier de jointures (JOIN ON). Une requte consiste en une demande dextraction dun ensemble dattributs, vrifiant une certaine proprit.
Les attributs demands peuvent tre pris dans diffrentes tables (ncessite des jointures ou produits cartsiens)
Les conditions peuvent porter sur les attributs demands, ou sur dautres attributs,
des mmes tables, ou non.
La rponse consiste en lensemble des donnes des attributs selectionns, tels que les
entres (compltes) associes vrifient les conditions souhaites.

6.2 Requtes simples


Une requte simple est une requte portant sur lextraction dattributs dune mme table, la
condition dextraction sexprimant uniquement laide des attributs de cette mme table.
Ainsi, tout se passe dans une unique table. Linstruction incontournable est :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

65

SELECT Att1, Att2, ...


FROM nom_table
WHERE onditions ;
La slection SELECT est voir comme une projection sur un sous-ensemble des colonnes
(on ne conserve que certaines colonnes), alors que la condition WHERE est voir comme une
slection dun sous-ensemble de lignes (on ne garde que les lignes vrifiant les conditions
requises).
La clause WHERE est optionnelle. Si on ne lutilise pas, il sagit de lextraction des colonnes
souhaites, sans restriction :

SELECT instrument FROM instrument ;


retourne lensemble des instruments solistes prsents dans la base, savoir :

'luth'
'violon elle'
'violon'
'viole de gambe'
' lave in'
'piano'
'orgue'
'flte'
'hautbois'
'baryton'
'soprano'
' larinette'
' or'
'basson'
'haute- ontre'
Linstruction suivante :

SELECT instrument FROM instrument WHERE famille = ' laviers' ;


renvoie quand elle uniquement les instruments clavier :

' lave in'


'piano'
'orgue'
Remarquez que pour obtenir lensemble des familles dinstruments, on formule assez logiquement la requte :

SELECT famille FROM instrument ;


On reoit la rponse suivante, peu satisfaisante :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

66

' ordes pin es'


' ordes frottes'
' ordes frottes'
' laviers'
' laviers'
' laviers'
'bois'
'bois'
'voix'
'voix'
'bois'
' uivre'
'bois'
'voix'
Ainsi, SELECT ne supprime pas les redondances dans les rponses. On peut le forcer le faire
en ajoutant loption DISTINCT :

SELECT DISTINCT famille FROM instrument ;


On obtient :

' ordes pin es'


' ordes frottes'
' laviers'
'bois'
'voix'
' uivre'
Enfin, on peut remplacer la liste des attributs par * si on veut selectionner lensemble des
attributs de la table :

SELECT * FROM ompositeur WHERE naissan e = 1685 ;


On obtient :

'BAC 1',
'HAE 1',
'SCA 1',

'Ba h',
'Haendel',
'S arlatti',

'Johann Sebastian',
'Georg Friedri h',
'Domeni o',

1685,
1685,
1685,

1750
1759
1757

Voici la liste des tests au programme pour exprimer la condition WHERE :

= > < != <= >=

# omparaisons sur des nombres ou hanes de ara tre.

Par ailleurs, on peut utiliser des oprations sur les attributs, soit pour exprimer des tests, soit
pour former de nouvelles colonnes. Former de nouvelles colonnes se fait en indiquant dans
la clause SELECT les oprations faire partir des autres attributs pour crer cette colonne.

+ * - /

# Oprations arithmtiques usuelles

Voici quelques exemples. Retourner Nom Prnom pour les compositeurs morts entre 1820
et 1830 :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

67

SELECT nom, prenom FROM ompositeur WHERE mort >= 1820 AND mort <= 1830 ;
On obtient :

'Beethoven',
'S hubert',

'Ludwig (Van)'
'Franz'

Donner noms des compositeurs ns avant 1700 :

SELECT nom FROM ompositeur WHERE naissan e < 1700 ;


On obtient :

'Couperin',
'Ba h',
'Haendel',

'Franois'
'Johann Sebastian'
'Georg Friedri h'

Certaines oprations mathmatiques portant sur lensemble des valeurs dun attribut sont
possibles. Ce sont les fonctions agrgatives :

COUNT(*)
COUNT(ATTR)
AVG(ATTR)
SUM(ATTR)
MIN(ATTR)
MAX(ATTR)

# nombre de lignes
# nombre de lignes remplies pour et attribut
# moyenne
# somme
# minimum
# maximum

Les fonctions agrgatives servent dfinir de nouvelles colonnes, mais ne peuvent pas tre
utilises dans une condition. Par exemple, nom et ge du composteur mort le plus vieux :

SELECT nom, MAX(mort - naissan e) FROM ompositeur ;


Rponse :

'Ysae', 93
Les fonctions agrgatives peuvent sutiliser avec linstruction GROUP BY Att HAVING Cond
permettant de calculer les fonctions agrgatives sur des paquets de donnes prenant la mme
valeur pour lattribut Att, en ne gardant que les lignes vrifiant la condition Cond.
Par exemple, date de la premire sonate pour des compositeurs avant N dans lordre alphabtique :

SELECT ompositeur, oeuvre, MIN(date) FROM oeuvre


GROUP BY ompositeur, type HAVING ( ompositeur < 'N') AND (type = 'sonate') ;
Enfin, notons quil est possible dordonner les rsultats par ordre croissant (numrique ou alphabtique) grce ORDER BY. Par exemple, compositeurs ns entre 1870 et 1890, par ordre
de naissance :

SELECT nom, naissan e, mort FROM ompositeur


WHERE naissan e BETWEEN 1870 AND 1890 ORDER BY naissan e ;

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

68

6.3 Constructions ensemblistes


Lorsquon veut extraire des attributs de plusieurs tables, il faut utiliser des constructions
ensemblistes permettant de combiner plusieurs tables. Nous introduisons ici lunion, lintersection et le produit cartsien..
Cest partir de cette dernire construction quon construira les jointures permettant des
requtes complexes sur plusieurs tables.
Lintersection de deux extractions de deux table peut se faire condition que les attributs
extraits des deux tables soient de mme format. Le rsultat est alors lensemble des valeurs
de cet (ou ces) attribut commun aux deux tables. Chacune des deux tables peut elle-mme
tre le rsultat dune extraction prcdente.
La syntaxe utilise INTERSECT. Sur un exemple, identifiants de compositeurs ns entre 1700
et 1800 et ayant crit une sonate :

SELECT id omp FROM ompositeur WHERE naissan e>=1700 AND naissan e<=1800
INTERSECT
SELECT DISTINCT ompositeur FROM oeuvre WHERE type = 'sonate' ;
Une intersection peut souvent se reexprimer plus simplement avec une sous-requte et une
opration boolenne AND. Cela peut tre efficace lorsquon veut croiser deux tables compltes (par exemple deux tables de clients de deux filiales) :

SELECT * FROM table1


INTERSECT
SELECT * FROM table2
Lunion de deux tables est possible si les attributs sont en mme nombre et de mme type. Il
sagit des enregistrements prsents dans lune ou lautre de ces tables. Lunion ne conserve
que les attributs distincts.
Par exemple pour fusionner deux tables :

SELECT * FROM table1


UNION
SELECT * FROM table2
Ici encore, il est souvent possible de remplacer avantageusement une union par une opration boolenne OR.
La dernire opration ensembliste est le produit cartsien. Le produit cartsien de deux tables
R 1 et R 2 est lensemble des n+p-uplets (x1, . . . , xn , y 1 , . . . , y p ), pour toutes les (x1, . . . , xn ) R 1
et (y 1 , . . . , y p ) R 2 , sans proccupation de concordance des attributs de R 1 et R 2 qui pourraient tre relis.
Le produit cartsien se fait en extrayant simultanment les colonnes des deux tables :

SELECT * FROM tab1, tab2 ;


On peut faire le produit cartsien dextractions de deux tables. Dans ce cas, on liste les attributs garder aprs SELECT, en prcisant dans quelle table lattribut se trouve par une notation suffixe. Si lattribut (sous le mme nom) napparat pas dans les deux tables, on peut
omettre la notation suffixe (il ny a pas dambigut) :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

69

SELECT tab1.Att1, Att2, tab2.Att3 FROM tab1, tab2 ;


Dans cet exemple, lattribut Att2 est suppos nexister que dans lune des deux tables.
Pour viter des lourdeurs dcriture (dans les conditions), et pouvoir rfrer plus simplement
aux diffrents attributs (cest utile aussi lorsquun attribut est obtenu par un calcul et non
directement), on peut donner un alias aux attributs selectionns :

SELECT tab1.Att1 AS B1, Att2*Att4 AS B2 , tab2.Att3 AS B3 FROM tab1, tab2 ;


Ici, on suppose que Att2 et Att4 sont deux attribus numriques. On pourra utiliser les valeurs des attributs de la nouvelle table via les alias B1, B2, et B3.
Le produit cartsien est une opration coteuse et peu pertinente en pratique si elle nest
pas utilise en parallle avec une opration de slection des lignes. En effet, on associe le
plus souvent des lignes nayant rien voir, par exemple une ligne consacre une oeuvre de
Mozart et une ligne consacre aux donnes personnelles de Stravinsky. Mais cette opration
est le point de dpart de la notion de jointure.
La technique de la jointure permet de former une table laide dune selection dattributs
provenant de deux tables diffrentes : plus prcisment, une jointure de deux tables consiste
considrer le produit cartsien de ces deux tables (ou dextractions), en identifiant deux
colonnes (une de chaque table), de sorte ne garder dans le produit cartsien que les nuplets tels que les valeurs soient les mmes pour ces deux attributs.
En dautre terme, une jointure revient une instruction de slection sur le produit cartsien.
Par exemple, pour slectionner deux attributs de chaque table en faisant une jointure en
identifiant lattribut T4 de la table 2 et lattribut T1 de la table 1 :

SELECT T1.Att1, T1.Att2, T3.Att3 FROM T1, T2 WHERE T1.Att1 = T2.Att4 ;


Un exemple concret :

SELECT nom, prenom, oeuvre FROM ompositeur, oeuvre WHERE id omp = ompositeur
Rsultat partiel :

('Weill', 'Kurt', 'Aufstieg und Fall der Stadt Mahagony')


('Weill', 'Kurt', 'Die Dreigros henoper')
Une autre syntaxe parfois plus commode (notamment pour itrer le procder en oprant des
jointures successives) se fait avec JOIN ... ON ... :

SELECT nom, prenom, oeuvre FROM ompositeur JOIN oeuvre ON id omp = ompositeur ;
On peut combiner cette jointure avec une slection conditionnelle WHERE. Par exemple, oeuvres
crites par un compositeur moins de 18 ans :

SELECT nom, prenom, oeuvre FROM ompositeur JOIN oeuvre ON id omp = ompositeur
WHERE date - naissan e <= 18 ORDER BY nom ;
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

70
On peut faire des jointures successives si on veut des attributs de tableaux plus loigns, ou
si on veut extraire des donnes de plus de deux tables :

SELECT nom, prenom, oeuvre.oeuvre, soliste.instrument


FROM ompositeur JOIN oeuvre ON id omp = ompositeur
JOIN soliste ON soliste.oeuvre = idoeuvre
JOIN instrument ON instrument.instrument = soliste.instrument
WHERE famille = 'bois' ORDER BY nom ;

6.4 Requtes composes


Dans ce paragraphe, on utilisera la table suivante :

On a dja vu HAVING, qui effectue une slection en aval dune agrgation. Par exemple, donner les moyennes par filire :

SELECT filiere,AVG(noteba ) FROM eleves GROUP BY filiere ;


et ne garder que les moyennes strictement suprieures 14.4 :

SELECT filiere,AVG(noteba ) FROM eleve GROUP BY filiere HAVING AVG(noteba ) > 14.4 ;
Voyons un exemple quivalent celui plus haut, mais sans HAVING :

SELECT filiere,moy
FROM (SELECT filiere,AVG(noteba ) FROM eleve GROUP BY filiere)
WHERE AVG(noteba )>14.4 ;
Ici, on effectue une premire requte ( lintrieur des parenthses) produisant des lignes
de la forme filiere, moyenne, puis on rutilise immdiatement la table produite dans une
nouvelle requte. Celle-ci est quivalente la premire et produit le mme rsultat.
Il faut bien comprendre quappliquer des requtes une table produit une nouvelle table !
Un autre exemple est le suivant : quels sont les lves ayant eu la plus haute note au bac ? Ici,
il faut rcuprer dabord la plus haute note au bac, puis refaire une requte pour slectionner
les lves ayant eu cette note. En SQL, on obtient :

SELECT * FROM eleve WHERE noteba =(SELECT MAX(noteba ) FROM eleve) ;


Ici, on utilise lidentification entre une table une ligne et une colonne et la valeur de cette
case. Attention, on pourrait tre tent dcrire quelque chose comme :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

71

SELECT nom,prenom,MAX(noteba ) FROM eleve ;


qui na pas vraiment de sens, mais fonctionne en SQL. Le rsultat produit est invariablement
une table avec une seule ligne : on obtient les nom et prnom dun seul lve ayant eu la
meilleure note au bac (avec cette note).
Pour conclure, retenir quon peut faire des sous-requtes en les plaant entre parenthses,
et quon peut utiliser comme valeur une table une ligne et une colonne pour faire une
slection.

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

72

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

Chapitre 2
Cours de deuxime anne
1 Piles
1.1 Gnralits
En informatique, une pile (en anglais stack) est une structure de donnes fonde sur le principe dernier arriv, premier sorti (ou LIFO pour Last In, First Out ), ce qui veut dire que
les derniers lments ajouts la pile seront les premiers tre rcuprs.

Le fonctionnement est celui dune pile dassiettes : on ajoute des assiettes sur la pile, et on
les rcupre dans lordre inverse, en commenant par la dernire ajoute.
Sur la figure suivante on empile A puis B et ensuite on dpile dans lordre B, puis A.

73

74
Les Piles ont beaucoup dapplications :
Dans un navigateur web, une pile sert mmoriser les pages Web visites. Ladresse
de chaque nouvelle page visite est empile et lutilisateur dsempile ladresse de la
page prcdente en cliquant le bouton Afficher la page prcdente .
Lvaluation des expressions mathmatiques en notation post-fixe (ou polonaise inverse) utilise une pile.
La fonction Annuler la frappe (en anglais Undo) dun traitement de texte mmorise
les modifications apportes au texte dans une pile.
Un algorithme de recherche en profondeur dans un graphe utilise une pile pour mmoriser les nuds visits.
Par exemple, on peut trs simplement inverser les lments contenus dans un tableau
ou dans une chane de caractres (pour tester un palindrome) en utilisant une pile. Il
suffit dempiler les lments sur une pile puis de reconstituer le tableau (ou la chane)
inverse en dsempilant les lments.
Un des gros avantages des piles est quil nest pas ncessaire de connatre lavance la taille
de la pile, cest--dire le nombre dlments quon va empiler.

1.2 Primitives
Pour manipuler les Piles, on dispose des fonctions suivantes, appeles primitives.
Trois primitives indispensables :
Empiler. Ajoute un lment sur la pile. Terme anglais correspondant : Push .

Dsempiler. Enlve un lment de la pile et le renvoie. Terme anglais correspondant :


Pop .

La pile est-elle vide ? Renvoie vrai si la pile est vide, faux sinon. Terme anglais isempty .
Dautres primitives peuvent tre obtenues partir des 3 premires :
Nombre dlments de la pile. Renvoie le nombre dlments dans la pile.

Quel est llment de tte ? Renvoie llment de tte sans le dpiler. Terme anglais correspondant : Peek .
Vider la pile. Dsempiler tous les lments. Terme anglais correspondant : Clear .

Dupliquer llment de tte et changer les deux premiers lments. Existe sur les calculatrices fonctionnant en notation polonaise inverse (style marque HP). Termes anglais
correspondants : Dup et Swap respectivement.

En Python, on utilise des listes. On ne sautorise aucune fonction excepte les trois suivantes
qui correspondent aux primitives indispensables : les mthodes append() et pop() et le test
dgalit la liste vide.
1
2
3
4
5
6
7

pile =[5 ,3 ,4 ,5
pile . append (1)
print pile
[5 ,2 ,4 ,5 ,1
pile . pop ()
1
print pile

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

75
8
9
10

[5 ,2 ,4 ,5
pile ==[
False

Remarquer que la mthode append() renvoie None alors que la mthode pop() renvoie llment dsempil (ou une erreur si la pile est vide).
On peut ensuite programmer les autres primitives. On modlise ainsi des piles non bornes.
Dans certains cas, on peut nutiliser que des piles bornes (limitation impose par le logiciel,
ou taille mmoire rduite). Dans ce cas, si N N est la taille limite dune pile borne, on
utilise en Python une liste de taille N , qui peut sinitialiser par les instructions pile=[0*N
ou pile=[ 0 for k in range(N) .
Par convention le premier lment de la liste va donner la longueur de la pile, et les autres
lments seront les lments de la pile.

 Exemple. Pour N = 8, pile=[3,2,1,4,0,0,0 est une pile de longueur 3.


Les primitives indispensables se programment ainsi :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

def push ( pile ,x ):


global N
assert pile [0 < N
n= pile [0
pile [ n +1= x
pile [0+=1
def isempty ( pile ) :
return pile [0==0
def pop ( pile ):
assert not ( isempty ( pile ) )
n= pile [0
pile [0 -=1
return pile [n

1.3 Files
En informatique, une file (queue en anglais) est une structure de donnes base sur le principe du premier entr, premier sorti , en anglais FIFO (First In, First Out), ce qui veut dire
que les premiers lments ajouts la file seront les premiers tre rcuprs.
Le fonctionnement ressemble une file dattente la poste : les premires personnes arriver sont les premires personnes sortir de la file.

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

76
Les applications sont diffrentes de celles des piles :
Mmoriser temporairement des transactions qui doivent attendre pour tre traites
dans lordre darrive.
Les serveurs dimpression, qui doivent traiter les requtes dans lordre dans lequel
elles arrivent, et les insrent dans une file dattente (ou une queue).
Certains moteurs multitches, dans un systme dexploitation, qui doivent accorder
du temps-machine chaque tche, sans en privilgier aucune.
Pour crer toutes sortes de mmoires tampons (en anglais buffers ).

2 Rcursivit
2.1 Gnralits
En informatique pratique les fonctions rcursives sont simplement des fonctions dont le
calcul ncessite dinvoquer la fonction elle-mme. Cest lanalogue des formules de rcurrences en mathmatiques.
Les fonctions non rcursives seront appeles fonctions itratives.

 Exemple. La fonction factorielle vrifie 0! = 1 et (n + 1)! = (n + 1) n!. Elle se programme

donc de manire itrative avec une boucle for :


1
2
3
4
5

def fa torielle(n ):
fa t =1
for k in range (2 , n +1) :
fa t = fa t *k
return fa t

ou une boucle while :


1
2
3
4
5
6
7

def fa torielle2( n):


fa t =1
k =2
while k <= n:
fa t = fa t *k
k +=1
return fa t

On peut aussi transcrire la formule de rcurrence en une fonction rcursive :


1
2
3
4
5

def fa torielle_re ( n):


if n ==0 or n ==1:
return 1
else :
return n* fa torielle_re (n -1)

B Cette exemple montre les trois grands principes dune fonction rcursive :
Une fonction rcursive doit comporter une close darrt qui consiste en la donne dun
ou plusieurs cas de base : cest le type de la sortie de cette close qui va dterminer le
type de la sortie de la fonction.
Une fonction rcursive doit appeler la close darrt au bout dun nombre fini dtapes
(ce qui assure la terminaison de lalgorithme).
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

77
Une fonction rcursive sappelle elle-mme, mais avec diffrentes valeurs de (ou des)
largument(s).
La structure gnrale est donc la suivante :

def fon tion_re ursive ( param tre ) :


if ... :
# lose d ' arr t
return ... # ette ligne d termine le type de la
variable de sortie
4
else :
5
return ... # instru tions ontenant un appel
fon tion_re ursive
1
2
3

On remarque que linstruction return doit tre prsente au moins deux fois : une fois pour
la close darrt, une fois pour lappel rcursif.

2.2 Exemples plus volus


Il est possible de donner plusieurs closes darrt grce linstruction elif :
1
2
3
4
5
6
7

def fa torielle_re ( n):


if n ==0:
return 1
elif n ==1:
return 1
else :
return n* fa torielle_re (n -1)

Dans lexemple de la fonction fa torielle_re , lappel du rang n lance lappel du rang


n-1, ce qui nest pas sans rappeler le principe de rcurrence simple en mathmatiques.
En fait, il est aussi possible dappeler la fonction avec dautres valeurs du paramtres ; ceci se
rapproche alors du principe de rcurrence forte .
Par exemple le calcul de x n peut se programmer en version itrative :
1
2
3
4
5

def puissan e (x ,n ):
puiss =1
for k in range (n )
puiss *= x
return puiss

mais aussi de faon rcursive :


1
2
3
4
5
6
7

def puissan e_re (x , n):


if n ==0:
return 1
elif n ==1:
return x
else :
return x* puissan e_re (x ,n -1)

Mais on peut acclrer un peu lalgorithme en utilisant les identits suivantes :


(
2
x 2k = x k
2
x 2k+1 = x x k
On obtient le programme rcursif :

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

78
1
2
3
4
5
6
7
8
9

def speed_puissan e_re (x ,n) :


if n ==0:
return 1
else :
r = speed_puissan e_re (x ,n /2) # Python 2.7
if n %2==0:
return r *r
else :
return x *r* r

On voir sur cet exemple quune instruction du type speed_puissan e_re (x,n/2)*speed_
puissan e_re (x,n/2) est trompeuse, puisque les deux appels ne vont pas se faire en
mme temps et beaucoup de calculs identiques vont tre effectues deux fois ; do lintrt
de la variable auxiliaire r.
Il est aussi possible de dfinir des fonctions mutuellement rcursives. Il suffit de les crire
lune la suite de lautre :
1
2
3
4
5
6
7
8
9
10
11

def pair ( n):


if n ==0:
return True
else :
return impair (n -1)
def impair (n ):
if n ==0:
return False
else :
return pair (n -1)

Remarquons quen utilisant lvaluation paresseuse (= retarde) des oprateurs or et and, on


aurait pu crire plus brivement :
1
2
3
4
5

def pair ( n):


return n ==0 or impair (n -1)
def impair (n ):
return n !=0 and pair (n -1)

2.3 Pile dexcution dune fonction rcursive


Les appels successifs dune fonction rcursive sont stocks dans une pile : cest la phase de
descente. Une fois que la close darrt est demande, les appels sont ensuite dsempils jusqu arriver lappel initial : cest la phase de remonte.
Par dfaut, Python limite 1000 le nombre dappels rcursifs. Tout dpassement provoquera
une erreur RuntimeError: maximum re ursion depth ex eeded. On peut augmenter la
taille de la pile en utilisant le module sys. Par exemple, pour une pile de taille 2000 :
1
2

import sys
sys . setre ursionlimit (2000)

La figure suivante montre les phases de descente et de remonte pour le calcul de 6!.

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

79

On peut aussi visualiser lexcution pas pas sur le site :

http://www.pythontutor. om/visualize.html#mode=edit.

2.4 Terminaison et correction dune fonction rcursive


Reprenons la fonction factorielle rcursive :
1
2
3
4
5

def fa torielle_re ( n):


if n ==0 or n ==1:
return 1
else :
return n* fa torielle_re (n -1)

On peut remarquer que lappel de fa torielle_re (-1) ne va sarrter quune fois dpasse la capacit de la pile dexcution. On dit que la fonction ne termine pas dans tous les
cas.
On peut corriger ce problme en levant une exception avec linstruction assert :
1
2
3
4
5
6

def fa torielle_re ( n):


assert n >=0 , 'n doit tre >=0 '
if n ==0 or n ==1:
return 1
else :
return n* fa torielle_re (n -1)

Dans ce cas la fonction termine dans tous les cas : en effet, soit on lui donne un entier n < 0
et on tombe sur lexception, soit on lui donne un entier n 0, et dans ce cas les diffrents
appels rcursifs vont amener un appel avec largument 1 (ou 0 si n = 0 au dpart) qui fait
partie de la close darrt, et donc le programme termine aussi dans ce cas l.
On peut donc retenir la mthode gnrale suivante : pour montrer quun algorithme rcursif
termine, il faut montrer que, pour toutes valeurs de largument, on arrivera en un nombre
fini dtapes un appel de la close darrt.
B Il existe des fonctions rcursives pour lesquelles on ne sait pas dmontrer la terminaison.
Par exemple la fonction de Syracuse :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

80
1
2
3
4
5
6
7
8

def syra use (n) :


if n ==0 or n ==1:
return 1
else :
if n %2==0:
return syra use ( n /2) # Python 2.7
else :
return syra use (3* n +1)

Pour viter les valeurs de largument pour lesquelles lalgorithme de ne termine pas, on peut
aussi utiliser les instructions while et input pour redemander une valeur lutilisateur (et
on suppose quil le fera au bout dun nombre fini dessais. . .) :
1
2
3
4
5
6
7
8

def fa torielle_re ( n):


while n <0:
n = input ( 'n doit tre positif , re ommen ez: ')
n = int (n ) # input donne une ha ne de ara t res
if n ==0 or n ==1:
return 1
else :
return n* fa torielle_re (n -1)

Examinons maintenant le problme de la correction dun algorithme rcursif, cest--dire de


la preuve que lalgorithme effectue bien les tches souhaites.
La mthode est naturelle : on utilise une dmonstration par le principe de rcurrence (simple
ou forte).
Par exemple, pour dmontrer la correction de la fonction fa torielle_re , on considre
le prdicat :
Hn : la fonction fa torielle_re (n) donne en sortie n!
Il est clair que H0 est vraie : cest la close darrt. Supposons Hn vraie un rang n N fix.
Linstruction fa torielle_re (n+1) excute linstruction (n+1)*fa torielle_re (n).
Daprs lhypothse de rcurrence Hn , linstruction fa torielle_re (n) renvoie n! et donc
linstruction fa torielle_re (n+1) renvoie (n + 1) n! = (n + 1)! : Hn+1 est donc vraie.
Daprs le principe de rcurrence, Hn est vraie pour tout n N : la correction de lalgorithme
est donc dmontre pour les entiers naturels (remarquer que nous ne sommes pas intresss
au cas n < 0).
Pour allger la rdaction, peut aussi dmontrer simultanment la terminaison et la correction
de lalgorithme rcursif. Par exemple, pour la fonction fa torielle_re , on considre le
prdicat :
Hn : la fonction fa torielle_re (n) termine et donne en sortie n!
Il est clair que H0 est vraie : cest la close darrt. Supposons Hn vraie un rang n N fix.
Linstruction fa torielle_re (n+1) excute linstruction (n+1)*fa torielle_re (n).
Daprs lhypothse de rcurrence Hn , linstruction fa torielle_re (n) termine et renvoie n! et donc linstruction fa torielle_re (n+1) termine et renvoie (n +1)n! = (n +1)! :
Hn+1 est donc vraie. Daprs le principe de rcurrence, Hn est vraie pour tout n N : la terminaison et la correction de lalgorithme sont donc dmontres pour les entiers naturels.
B Pour la fonction rcursive syra use, elle renvoie toujours 1 (pour un argument dans N),
mais personne na russi le dmontrer pour le moment.

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

81

2.5 Complexit dun algorithme rcursif


Rappelons qutudier la complexit dun algorithme, cest valuer le nombre doprations
lmentaires quil effectue, ou encore son occupation mmoire lors de son excution.

Si n est son argument, on note C (n) le nombre doprations lmentaires effectues, et A(n)
loccupation mmoire. On cherche ensuite, en tudiant lalgorithme une relation de rcurrence vrifie par la suite C (n), ou encore la suite A(n). On essaye ensuite den dduire une
expression explicite mais cela est rarement possible cause de la difficult des calculs. On
cherche souvent dominer C (n) et A(n) par une des suites de rfrences (n , ln(n), n! . . .).
Par exemple, pour la fonction fa torielle_re , on trouve C (n) = 1 + C (n 1) : en effet, on
effectue une multiplication et lappel rcursif au rang n 1. On a donc C (n) = n. On obtient
la mme complexit que pour la version rcursive.

Donnons un exemple plus complexe : la suite de Fibonacci. Elle est dfinie par u 0 = u 1 = 1
et, pour tout n N : u n+2 = u n+1 + u n . La version itrative est la suivante :
1
2
3
4
5
6
7
8

9
10
11
12
13
14

def fibo ( n):


u =1 # u repr sente u_k
v =1 # v repr sente u_ { k +1}
for k in range (n -1) :
u ,v=v ,u +v # affe tation simultan e en Python
return v
\ end { pyton }
La r urren e d ' ordre $2$ oblige l ' utilisation de deux variables
\ verb +u + et \ verb +v+, e qui d grade la lisibilit du
programme . La version \ underline { r ursive } est plus simple :
\ begin { python }
def fibo_re (n) :
if n ==0 or n ==1:
return 1
else :
return fibo_re (n -1) + fibo_re (n -2)

Si note A(n) loccupation mmoire de fibo_re (n), on trouve que A(n) = A(n 1)+ A(n 2).
On montre alors quil existe un constante C > 0 telle que :
p !n
5
A(n) C . 1 +
n+
2

ce qui est trs mauvais (pour la version itrative A(n) = 2 et C (n) = n 1). En effet, certains
termes de la suite sont calculs un trs grand nombre de fois (alors quune fois suffirait). On
peut le visualiser sur la figure suivante, ou le calcul de u 6 a demand de calculer 8 fois u 2 .

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

82

Pour rsoudre ce problme, il faudrait enregistrer dans un tableau les termes dj calculs :
cette technique sappelle la mmosation.
Grce linstruction time() du module time, on peut comparer les vitesse dexcution des
versions itratives et rcursives :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

from __future__ import uni ode_literals # a ent dans les plots


from time import time
repetitions =10
iteratif =[
for k in range ( repetitions):
t= time ()
fibo ( k) # on al ule les premiers termes de la suite
t= time () -t
iteratif . append ( t) # on sto ke les temps de al uls
re ursif =[
for k in range ( repetitions):
t= time ()
fibo_re (k)
t= time () -t
re ursif . append ( t)
import matplotlib. pyplot as plt
abs isses = range ( repetitions)
plt . plot ( abs isses , re ursif , olor = 'b ', label = ' Version r ursive ')
plt . plot ( abs isses , iteratif , olor = 'r ', label = ' Version it rative ')
plt . legend ( lo =2) # en haut gau he

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

83
On obtient :

0.00005

Version rcursive
Version itrative

0.00004

0.00003

0.00002

0.00001

0.00000
0

2.6 Version rcursive des algorithmes vus en premire anne


2.6.1 Recherche dun lment dans une liste trie
On dispose dune liste l de de nombres dj trie dans lordre croissant. On veut dterminer
si un lment x appartient cette liste et donner la position dun lment gal x (ne pas
perdre de vue quil peut en exister plusieurs).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

def re her he (l ,x ):
if len (l ) ==0: # lose d ' arr t
return -1
else :
k = len (l ) /2 # Python 2.7
if l [k == x: # x est au milieu de la liste
return k
elif l[ k> x: # on her he gau he
return re her he (l [: k ,x )
else :
test = re her he (l [k +1: , x ) # droite
if test == -1: # non trouv
return -1
else : # trouv
return test + k +1 # orre tion de la position

Dans ce cas, on sait lavance si la recherche doit se faire dans la partie gauche ou dans la
partie droite, contrairement au cas prcdent.
Si on note C (n) le nombre de tests boolens,
dans

le pire des cas, pour une liste de taille n, on


a C (n) = 4 + C (n/2) et donc C (n) = O log2 (n) . Cette fois on obtient une nette amlioration
par rapport la version itrative.

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

84
2.6.2 Algorithme de dichotomie
Le but est de trouver une solution approche de lquation f (x) = 0 sur un segment [a, b].
Pour cela on se base sur le thorme des valeurs intermdaires : si f est continue sur [a, b],
et si f (a) et f (b) sont de signes contraires (au sens large), alors f sannule au moins une fois
sur [a, b].
a +b
. Si f (a) et f (c) sont de
2
signes contraires, on cherche la solution dans [a, c], sinon on la cherche dans [c, b]. On ritre
ensuite ce processus. Comme on divise chaque fois lintervalle en 2, on arrive au bout de
ba
n tapes un intervalle [a , b ] de longueur n : a et b sont alors des valeurs approches
2
ba
de la solution cherche, avec une prcision de
. Si on souhaite une prcision de > 0
2n
ba
donne, il suffit de choisir le nombre n ditrations tel que n < .
2
Lalgorithme consiste couper le segment en son milieu c =

Lalgorithme scrit naturellement de manire rcursive :


1
2
3
4
5
6
7
8
9
10

def di ho (f ,a ,b , eps ) :
assert f (a) *f (b) <=0 , 'on ne sait pas si f s '' annule '
if b -a < eps : # lose d ' arr t
return a
else :
=( a +b) /2. # Python 2.7
if f (a) *f ( ) <0:
return di ho (f ,a , , eps ) # re her he dans [a ,
else :
return di ho (f , ,b , eps ) # re her he dans [ ,b

Le nombre ditrations est le mme que pour la version itrative : cest le plus petit entier n
ba
tel que n < .
2

3 Algorithmes de tri
Dans cette section, nous allons prsenter plusieurs algorithmes permettant de trier une liste
(ou un tableau) de nombres.

3.1 Gnralits sur les algorithmes de tri par comparaisons


Nous donnons un rsultat trs gnral.
Thorme. Si cn est le nombre de comparaisons effectues par un algorithme de tri, pour
trier une liste de n nombres, alors n. log2 (n) = O (cn ).

Pour cette raison, un algorithme de tri sera dit optimal lorsque cn = O log2 (n) .

B Lorsquon ajoute des hypothses sur les objets trier, il existe des algorithmes plus rapides !
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

85
Donnons ensuite une notion qui va permettre de comparer les performances des diffrents
algorithmes de tri : on dit quun tri est fait en place si il ne ncessite pas lutilisation dune
liste (ou tableau) auxiliaire. Dans ce cas, la complexit spatiale (= occupation en mmoire)
de lalgorithme est constante.

3.2 Tri par insertion (insertion sort)


3.2.1 Prsentation de lalgorithme
Cest le tri naturellement utilis pour trier des cartes : prendre les cartes (mlanges) une
une sur la table, et former une main en insrant chaque carte sa place.
Pour une liste de nombres t le principe est le suivant :
On parcourt la liste de gauche droite.

Au moment o on considre le k-me lment (not t[k-1 en Python), les k 1 lments


qui le prcdent sont dj tris entre eux.
On insre alors le k-ime lment dans la portion du tableau qui le prcde (note t[:k),
de telle sorte que les k premiers lments soient leur tour tris : pour cela on parcourt le
tableau de droite gauche et tant que les lments sont plus grand que t[k-1, on les dcale
dune position vers la droite (ce qui conserve le tri prcdent) ; ds quun lment plus petit
est trouv, on place juste ct la valeur de t[k-1.
La figure suivante donne un exemple dinsertion :

Et sur une liste quon trie entirement :

Le code Python est le suivant :


PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

86
1
2
3
4
5
6
7
8
9
10
11

def tri_insertion (t) :


# attention une liste Python est un param tre pass par r f ren e
for k in range (1 , len ( t)) :
j =k -1
x =t[ k
while j >=0 and t[ j> x: # et non pas l [j> x and j >=0
t[j +1= t [j # d alage droite
j=j -1
t [j +1= x # insertion
# pas besoin de return t puisque t a t pass e par r f ren e
# la fon tion ne renvoie rien en sortie

Par exemple :
1
2
3
4

>>>
>>>
>>>
[1 ,

t =[5 ,2 ,4 ,6 ,1 ,3
tri_insertion (t)
t
2, 3, 4, 5, 6

la place de t est un paramtre pass par rfrence, on dit parfois que t est une variable
modifie en place.
On remarque que le tri par insertion est tri fait en place, sa complexit spatiale est donc faible.
En utilisant la fonction enumerate on peut crire une version peut-tre plus lisible du programme prcdent. Linstruction for k,x in enumerate(t) parcours la liste t de telle sorte
que k prenne successivement les valeurs 0, 1, . . ., len(t), et simultanment x prend les valeurs t[0, t[1, . . ., t[len(t).
1
2
3
4
5
6
7

def tri_insertion2 (t ):
for k ,x in enumerate ( t): # x= t[ k
j =k -1
while j >=0 and t[ j> x:
t[j +1= t [j
j=j -1
t [j +1= x

3.2.2 Complexit
Avec le module time, on peut valuer empiriquement la complexit en regardant le temps
de calcul pour trier des listes de nombres de taille variant de 1 300. Pour crer des liste
alatoires on utilise la fonction randint du sous-module random du module numpy.
1
2
3
4
5
6
7
8

from time import time


import numpy . random as rd
def omplexite_insertion ( n):
ordonnees =[
for k in range (n +1) :
liste = rd . randint (0 , k +1 , k +1)
# k +1 nombres entiers entre 0 et k

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

87
9
10
11
12
13
14
15

temps = time ()
tri_insertion ( liste )
temps = time () - temps
ordonnees . append ( temps )
abs isses = range (n +1)
plt . plot ( abs isses , ordonnees , linestyle = ': ' , marker = 'o ')
plt . show ()

On obtient la courbe suivante qui suggre une complexit en O (n 2 ), o n est la taille de la


liste :

Nous allons donc valuer la complexit de lalgorithme en fonction de la taille n dune liste
donne en argument dentre.
Dans le pire des cas, la boucle while seffectue jusqu ce que la variable j prenne la valeur
1, et le nombre de comparaisons est gal k. Avec la boucle for on obtient que le nombre
total de comparaison est :
1 +2 + +k + +n 1 =

n(n 1)
2

Si on note C n la complexit temporelle (en ne prenant en compte que les comparaisons)


dans le pire des cas, on a donc :
n2
Cn
n+ 2
Remarquez que cette situation correspond au cas dun tableau tri au dpart dans lordre
dcroissant.
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

88
Dans le meilleur des cas, la boucle while ne seffectue pas, et le nombre de comparaisons est
gal 1. Avec la boucle for on obtient que le nombre total de comparaison est :

1 +1 + +k + +1 = n 1
Si on note cn la complexit temporelle (en ne prenant en compte que les comparaisons) dans
le meilleur des cas, on a donc :
cn

n+

Remarquer que cette situation correspond au cas dun tableau dj tri au dpart dans lordre
croissant.

Ce tri nest donc pas optimal mais il est tout de mme beaucoup utilis. Empiriquement, il
est tabli quil est le plus rapide sur des donnes presque tries, ou sur des listes (ou tableaux)
de petite taille.

3.3 Tri rapide (quick sort)


3.3.1 Prsentation de lalgorithme
On choisit dans la liste un lment particulier (en gnral le premier), not x. On cre alors
deux sous-tableaux : un contenant les lments strictement infrieurs x, et lautre contenant les lments suprieurs ou gaux x. On relance le tri de manire rcursive sur ces deux
sous-tableaux qui deviennent donc des listes tries, et il ne reste plus qu les concatner, en
intercalant le pivot entre les deux. En effet, on remarque quon reforme ainsi la liste initiale
mais sous forme trie.

Cet algorithme est un exemple dune mthode gnrale utilise en rcursivit, appele diviser pour rgner : on divise le problme initial en deux sous-problmes quon sait rsoudre,
et on revient ensuite au problme initial. Dans le cas du tri rapide, les appels rcursifs sont
lancs jusqu tomber sur des listes de taille 1 ou 0, qui sont dj tries, et il ne reste plus
qu les concatner dans le bon ordre.

La figure suivante illustre ce tri sur un exemple :


PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

89

Nous donnons une premire version nave :

def tri_rapide( t) :
if len (t ) <=1: # lose d ' arr t : tableau vide
return t # ou ave un seul l ment
else :
pivot =t [0 # hoix arbitraire du pivot
plus_petits =[ x for x in t if x < pivot
plus_grands =[ x for x in t [1: if x >= pivot
return tri_rapide( plus_petits) +[ pivot + tri_rapide(
plus_grands)
9
# on at nation et renvoi du r sultat
1
2
3
4
5
6
7
8

Si on ne souhaite pas utiliser les listes par comprhension, on peut crire :

def tri_rapide2(t ):
if len (t ) <=1: # lose d ' arr t : tableau vide
return t # ou ave un seul l ment
else :
pivot =t [0 # hoix arbitraire du pivot
plus_petits =[
plus_grands =[
for x in l [1::
if x < pivot :
plus_petits. append (x )
else :
plus_grands. append (x )
return tri_rapide( plus_petits) +[ pivot + tri_rapide(
plus_grands)
14
# on at nation et renvoi du r sultat
1
2
3
4
5
6
7
8
9
10
11
12
13

Ce premier algorithme naf illustre trs bien la mthode utilise, grce aux liste plus_petits
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

90
et plus_grands. Mais il a un gros dfaut : le tri ne se fait pas en place. Au cours de lexcution
il se cre beaucoup de tableaux auxiliaires et la complexit spatiale est alors trs importante.
Nous allons donner une version plus complique, mais pour laquelle le tri se fera en place : il
faut russir partitionner selon le pivot, mais sans crer de nouvelle liste auxiliaire, la seule
possibilit tant de permuter les lments de la liste deux deux.
Nous allons commencer par crer une fonction partition(t) qui va partitionner une liste
t en prenant le premier lment t[0 comme pivot.
Pour cela, on parcourt la liste de gauche droite ( partir de t[1]), de telle sorte que lorsquon
arrive llment t[i, les i premiers lments soient partitionns, cest--dire que :
leur partie gauche jusqu un indice appel position est forme des lments plus petits
(au sens strict) que le pivot,
leur partie droite (aprs lindice position) est forme des lments plus grands (au sens
large).

0
pivot

...
<pivot

position
<pivot

...
pivot

i
t[i]

...
?

len(t)-1

On compare alors t[i avec le pivot :


sil est plus grand (au sens large), on ne fait rien ;
sil est plus petit (au sens strict), on le permute avec llment t[position+1 et on
incrmente la variable position de +1.
Une fois arriv la fin de la liste, on permute les lments t[0 et t[position : le tableau
est alors partitionn comme souhait. On revoie en sortie la valeur de la variable position.
Comme une liste (ou un tableau) est un paramtre pass par rfrence, elle est modifie par
la fonction comme sil tait une variable globale.
1
2
3
4
5
6
7
8
9
10
11

def partition (t ):
assert t !=[ , 'on ne peut pas partitionner la liste vide '
pivot =t [0
position =0
for i in range (1 , len ( t)) :
if t [i< pivot :
t[i , t[ position +1= t[ position +1 , t[ i
position +=1
if position !=0:
t [0 , t[ position = t[ position , t [0
return position

Pour lancer le tri rcursif, nous allons devoir appliquer cette fonction sur une portion de la
liste, et non la liste entire. On adapte donc notre fonction pour quelle ne partitionne que
la portion t[a:b (forme des t[i pour t allant de a b 1). Le reste de la liste nest pas
modifi.
1
2
3

def partition (t ,a ,b) :


assert a <b , 'on ne peut pas partitionner la liste vide '
pivot =t[ a

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

91
4
5
6
7
8
9
10
11

position =a
for i in range (a +1 , b) :
if t [i< pivot :
t[i , t[ position +1= t[ position +1 , t[ i
position +=1
if position != a:
t [a, t[ position = t[ position , t[ a
return position

On peut crire le programme principal du tri rapide en place. Lui aussi doit pouvoir se lancer
sur des portions de liste, il aura donc trois arguments comme la fonction partition prcdente. En sortie, il ne renvoie rien mais la liste a t modifie.
1
2
3
4
5

def tri_rapide2(t ,a , b):


if a < b:
position = partition (t ,a , b)
tri_rapide2(t ,a , position )
tri_rapide2(t , position +1 , b)

Pour trier toute la liste t, il faut lancer tri_rapide2(t,0,len(t)). Comme ce nest pas trs
naturel, on peut crer une nouvelle fonction avec un seul argument dentre.
1
2

def qui ksort (t ):


tri_rapide2(t ,0 , len (t ))

3.3.2 Complexit
Comme pour le tri par insertion, on peut valuer empiriquement la complexit en regardant
le temps de calcul pour trier des listes de nombres de taille variant de 1 300.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

from time import time


import numpy . random as rd
def omplexite_qs (n) :
ordonnees =[
for k in range (n +1) :
liste = rd . randint (0 , k +1 , k +1)
# k +1 nombres entiers entre 0 et k
temps = time ()
qui ksort ( liste )
temps = time () - temps
ordonnees . append ( temps )
abs isses = range (n +1)
plt . plot ( abs isses , ordonnees , linestyle = ': ' , marker = 'o ')
plt . show ()

On obtient la courbe suivante qui suggre une complexit un peu plus que linaire, o n est
la taille de la liste :

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

92

Nous allons donc valuer la complexit de lalgorithme en fonction de la taille n dune liste
donne en argument dentre, et nous allons voir quelle nest pas linaire mais en O (n log2 (n)).
Dans le pire des cas, le rsultat de la fonction partition place systmatiquement le pivot en
dbut ou en fin de tableau. Les appels rcursifs se font donc sur un tableau vide et un tableau
de taille n 1. Avant de lancers les appels rcursifs, lappel la fonction partition effectue
n 1 comparaisons entre les lments du tableau.
Si on note C n la complexit temporelle (en ne prenant en compte que les comparaisons)
dans le pire des cas, on a donc :
C n = n 1 +C n1
On en dduit facilement que :
C n = (n 1) + (n 2) + + 1 + 0 +C 0 =
donc :
Cn

n+

n(n 1)
+C 0
2


O n2

Remarquer que cette situation correspond au cas dun tableau dj tri au dpart (dans nimporte quel ordre).
Dans le meilleur des cas, le rsultat de la fonction partition place systmatiquement le
j npik
vot en milieu de de tableau. Les appels rcursifs se font donc sur deux tableaux taille
.
2
Avant de lancers les appels rcursifs, lappel la fonction partition effectue n 1 comparaisons entre les lments du tableau.
Si on note cn la complexit temporelle (en ne prenant en compte que les comparaisons) dans
le meilleur des cas, on a donc :
cn = n 1 + 2.c n
2

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

93
Les calculs suivant prouvent que :
cn

n+

O n. log2 (n)

Cas 1. On commence par le cas o n est une puissance de 2 : n = 2p pour p N.


Pour simplifier les notations, posons x p = c2p .
On a donc la relation de rcurrence :
x p = c2p = 2p 1 + 2.c2p1 = 2p 1 + 2.x p1
On en dduit que :
xp

2 1) + 2. 2p1 1) + 22 . 2p2 1) + + 2p1 . 2 1) + 2p .x0


1 2p
+ 2p .x0
= p.2p
12
= p.2p + 1 2p + 2p .c0
=

Cas 2. On revient au cas gnral. Pour cela, on fait lhypothse raisonnable que la suite
(cn )nN est croissante (plus la taille des donnes trier est important, plus le nombre de
comparaisonest important).

On pose p = log2 (n) + 1 de sorte que log2 (n) p et donc :


n < 2p

On en dduit que :

cn c2p = p.2p + 1 2p + 2p .c0

mais on a aussi p log2 (n) + 1 donc :

log (n)+1

log2 (n)+1
log2 (n)+1
2
cn log2 (n) + 1 .2
+12
+2
.c0 = 2n log2 (n) + 1 1 + c0 1

et finalement :

cn

n+

O log2 (n)

Ce tri est donc optimal dans le meilleur des cas mais il ne lest pas dans le pire des cas.
Mais il se trouve quen pratique cest lalgorithme le plus rapide, il est donc empiriquement
le plus performant. Cette diffrence vient du fait que nous avons seulement dnombr les
comparaisons entre lments du tableau trier, alors quil se passe beaucoup dautre choses
lors de lexcution de lalgorithme (affectations etc. . .).

3.4 Tri fusion (merge sort)


3.4.1 Prsentation de lalgorithme
Nous allons encore crer un programme rcursif utilisant la mthode diviser pour rgner .
Pour le tri rapide, lide est de faire en sorte que les deux parties concatner donne directement le tableau tri (cest tout lintrt de la fonction partition), le dfaut tant quon
ne coupe pas toujours en deux parties gales. Pour le tri fusion, le principe est diffrent. On
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

94
coupe le tableau en deux morceaux toujours gaux, quon trie, puis reste ltape dlicate appele fusion. Elle consiste fusionner ces deux tableaux de telle sorte quon obtienne un
tableau tri.
La figure suivante illustre ce tri sur un exemple :

La fonction principale est la fonction fusion qui permet de fusionner deux tableaux tris
en un tableau tri. Pour cela on procde manire rcursive : le plus petit lment des deux
tableaux est plac en premire position du nouveau tableau, il reste ensuite fusionner les
deux tableaux privs de cet lment.
1
2
3
4
5
6
7
8
9
10
11

def fusion (t1 , t2 ) : # fusion de deux tableaux d j tri es


if t1 ==[: # premi re lose d ' arr t
return t2
if t2 ==[: # deuxi me lose d ' arr t
return t1
if t1 [0 < t2 [0:
# pour fusionner on pla e le plus petit l ment des 2 tableaux
en premier
# ' est le plus petit l ment global tableaux tri s
return [ t1 [0+ fusion ( t1 [1: , t2 ) # appel r ursif
else :
return [ t2 [0+ fusion (t1 , t2 [1:) # appel r ursif

La fonction qui effectue le tri fusion est trs simple :


1
2
3
4
5
6

def trifus (t ):
if len (t ) <=1: # lose d ' arr t
return t
else :
return fusion ( trifus (t [: len (t) /2) , trifus ( t[ len (t) /2:) )
# en Python 2.7 / est la division eu lidienne

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

95
On voir tout de suite lavantage de cet algorithme : la lecture est trs simple, et le fait de
toujours couper le tableau en deux parties gales va limiter le nombre de comparaisons.
Par contre la complexit spatiale est trs mauvaise, on utilise une fonction rcursive qui appelle elle-mme une fonction rcursive, et les oprations ne sont faites pas en place.
On peut donc esprer amliorer lalgorithme en le programmant en place. Pour cela, si on
dispose dun tableau dont les deux moitis sont tries, il faut tre capable de les fusionner
dans crer de tableau auxiliaire. Nous allons utiliser des permutations circulaires. Si on se
donne un tableau [x1 , x2 , . . . , xn1 , xn ], il devient aprs permutation circulaire :
[xn , x1 , x2 , . . . , xn1 ]
1
2
3
4
5

def perm_ ir (t ):
for k in range ( len (t) -1 ,0 , -1):
t [k, t[k -1= t[k -1 , t [k
# permutation ir ulaire: le dernier l ment devient le premier
# et les autres sont d al s vers la droite

Et on adapte pour lancer sur le sous-tableau t[i:j+1.


1
2
3
4
5

def perm_ ir (t ,i ,j) :


for k in range (j ,i , -1) :
t [k, t[k -1= t[k -1 , t [k
# permutation ir ulaire: le dernier l ment devient le premier
# et les autres sont d al s vers la droite

Ensuite, supposons quon dispose dun tableau t et dun indice m dans 0,len(t), de telle
sorte que les sous-tableaux t[:m et t[m: soient tris. Pour raliser la fusion, nous allons
parcourir le tableau de gauche droite de sorte que lorsquon arrive llment t[i :
t[:i est un sous-tableau dun tableau tri t[:j avec j > i et j m,
chaque lment de t[:i est infrieur ou gal x,
le tableau t[j: est tri.
...
t[j]

i
t[i]
tri

...

j
t[j]

...
?
tri

len(t)-1

On compare alors t[j avec t[i :


si t[jt[i, on incrment i de 1 ;
si t[j<t[i, on effectue une permutation circulaire sur le tableau t[i:j+1, puis
on incrmente i et j de 1.
On arrte lorsquon atteint la fin de la liste, ie j =len(t), ou lorsque i = j puisque dans ce
cas le tableau entier est dj tri (les deux parties tries se concatnent en une partie trie) !

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

96
1
2
3
4
5
6
7
8
9
10
11

def fusion (t ,m) :


# t [: m et t[ m : sont suppos s tri s
i =0 # pro hain l ment traiter
j=m
while j < b and i < j:
if t [j >= t[i :
i +=1
else :
perm_ ir (t ,i ,j) # permutation ir ulaire
i +=1
j +=1

Et on adapte au cas dun sous-tableau t[a:b.


1
2
3
4
5
6
7
8
9
10
11

def fusion (t ,a ,m , b):


# t[a :m et t [m :b sont suppos s tri s
i=a # pro hain l ment traiter
j=m
while j < b and i < j:
if t [j >= t[i :
i +=1
else :
perm_ ir (t ,i ,j) # permutation ir ulaire
i +=1
j +=1

On peut crire le programme principal du tri fusion en place. Lui aussi doit pouvoir se lancer
sur des portions de liste, il aura donc trois arguments comme la fonction fusion prcdente.
En sortie, il ne renvoie rien mais la liste a t modifie.
1
2
3
4
5
6

def trifus2 (t ,a ,b ): # trie t[ a:b


if b > a +1:
m = (a+ b) /2 # Python 2.7
trifus2 (T ,a , m)
trifus2 (T ,m , b)
fusion (T ,a ,m ,b)

Pour trier toute la liste t, il faut lancer trifus2(t,0,len(t)). Comme ce nest pas trs naturel, on peut crer une nouvelle fonction avec un seul argument dentre.
1
2

def tri_fusion( t) :
trifus2 (t ,0 , len (t))

3.4.2 Complexit
On peut valuer empiriquement la complexit en regardant le temps de calcul pour trier des
listes de nombres de taille variant de 1 300.

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

97
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

from time import time


import numpy . random as rd
def omplexite_ms (n) :
ordonnees =[
for k in range (n +1) :
liste = rd . randint (0 , k +1 , k +1)
# k +1 nombres entiers entre 0 et k
liste = list ( liste )
# il ne faut pas de tableaux numpy mais des listes ause du
omportement de +
temps = time ()
tri_fusion( liste )
temps = time () - temps
ordonnees . append ( temps )
abs isses = range (n +1)
plt . plot ( abs isses , ordonnees , linestyle = ': ' , marker = 'o ')
plt . show ()

On obtient la courbe suivante qui suggre la mme complexit que pour le tri rapide : O n. log2 (n) .

0.035

0.030

0.025

0.020

0.015

0.010

0.005

0.000
0

50

100

150

200

250

300

Nous allons donc valuer la complexit de lalgorithme en fonction de la taille n dune liste
donne en argument dentre.
Dans
j nde
k
j n k le pire des cas (tableau tri lenvers), lors de lappel de la fonction fusion, j varie
n 1, et i prend ses valeurs entre 0 et n 2, donc au total lalgorithme effectue
2
2
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

98
comparaisons. En gardant les notations des paragraphes prcdents, on a donc :
jn k
+ 2.C n
Cn =
2
2
et les mmes calculs que pour le tri fusion donnent :

C n = O n. log2 (n)
n+

jn k
1, donc au total lalDans le meilleur des cas(tableau tri), j ne varie pas et i varie de 0
2
jn k
gorithme effectue
comparaisons. En gardant les notations des paragraphes prcdents,
2
on a donc :
jn k
cn =
+ 2.c n
2
2
et les mmes calculs que pour le tri fusion donnent :

cn = O n. log2 (n)
n+

Ce tri est donc optimal ! Mais ce nest vrai quen prenant en compte le nombre de comparaisons. La version prsente a lavantage dtre en place, donc la complexit spatiale est
constante. Par contre le nombre daffectations est trs grand, et il parat peu rigoureux de ne
pas en tenir compte.

3.5 Comparaison empirique des trois algorithmes de tri


Nous allons comparer la rapidit des trois algorithmes de tri sur des tableaux alatoires de
taille comprise entre 0 et 300 lments ; comme on ne sintresse pas la complexit spatiale,
nous utilisons les versions non en place qui sont plus simples. Python dispose aussi de la
mthode sort() : si t est une liste alors linstruction t.sort() trie la liste en place.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

def omparaison_tri ( n):


ordonnees =[
for k in range (n +1) :
liste = rd . randint (0 , k +1 , k +1)
t = time ()
tri_insertion ( liste )
t = time () -t
ordonnees . append ( t)
abs isses = range (n +1)
plt . plot ( abs isses , ordonnees , linestyle = ': ' , marker = 'o ' , label = '
insertion ')
ordonnees =[
for k in range (n +1) :
liste = rd . randint (0 , k +1 , k +1)
t = time ()
tri_rapide( liste )
t = time () -t
ordonnees . append ( t)
plt . plot ( abs isses , ordonnees , linestyle = ': ' , marker = 'o ' , label = '
rapide ')

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

99
19
20
21
22
23
24
25
26
27
28

ordonnees =[
for k in range (n +1) :
liste = rd . randint (0 , k +1 , k +1)
t = time ()
trifus ( liste )
t = time () -t
ordonnees . append ( t)
plt . plot ( abs isses , ordonnees , linestyle = ': ' , marker = 'o ' , label = '
fusion ')
plt . legend ( lo =2)
plt . show ()

On obtient les courbes suivantes.

0.030

0.025

insertion
rapide
fusion
sort()

0.020

0.015

0.010

0.005

0.000
0

50

100

150

200

250

300

On retrouve quempiriquement le tri rapide est le meilleur en temps. La mthode sort()


de Python parat beaucoup plus efficace que les trois algorithmes prsents ; nous naborderons pas son fonctionnement (il faut simplement savoir quen pratique on mlange les
algorithmes de tri).

3.6 Recherche de la mdiane dans un tableau


Si on dispose dun tableau t=[t[0,t[1,...t[n-1 de nombres flottants de taille n, que
lon suppose tri, on dfinit la mdiane de t ainsi :
jn k
si n est impair, n = 2p + 1. La mdiane de t est llment t[p avec p =
;
2
si n est pair, n = 2p. Une mdiane de t est nimporte quel lment de lintervalle [t[p-1,t[p[
jn k
t [p 1] + t [p]
avec p =
. On choisit souvent le milieu de cet intervalle :
.
2
2
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

100
Pour dterminer la mdiane dun tableau quelconque de nombres flottants, il suffit donc de
le trier, puis dappliquer la dfinition
ci-dessus.
La complexit minimale est donc celle de

lalgorithme de tri, cest--dire O n. log2 (n) au minimum.

Il existe des algorithmes plus performants, appels algorithme de slection, qui permette de
trouver le k-ime plus grand lment dun tableau de nombre flottants, sans avoir trier
systmatiquement tout le tableau. Leur complexit est en moyenne linaire, ie en O (n).

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

Chapitre 3
Exercices de premire anne
1 Structure de donnes
1.1 Reprsentation des nombres

Exer i e 1 (Suite r urrente linaire instable) Dans cet exercice, on sintresse aux suites
(u n )nN vrifiant la relation de rcurrence linaire :
n N,

8
u n+2 = u n u n+1
3

(R)

1. Soit u vrifiant (R). Exprimer, pour tout n N, u n en fonction de u 0 et u 1 .


2. Donner une condition ncessaire et suffisante simple portant sur u 0 et u 1 pour que
(u n )nN converge.
3. On sintresse
dans un premier temps la suite vrifiant (R) avec les conditions ini(
u0 = 1
tiales
u1 = 1
(a) crire un programme prenant en entre n et retournant la valeur de u n (en utilisant la relation de rcurrence, cest--dire sans utiliser la formule tablie la premire question).
(b) Vrifier la solution obtenue en calculant puis reprsentant les 10 premiers termes
(en reliant les points de coordonnes (n, u n ) ).
(
u0 = 3
4. On sintresse maintenant la suite vrifiant (R) avec les conditions initiales
u1 = 1
(a) crire un programme prenant en entre n et retournant la valeur de u n (en utilisant la relation de rcurrence, cest--dire sans utiliser la formule tablie la premire question).
(b) Vrifier la solution obtenue en calculant puis reprsentant les 10 premiers termes.
(c) Recommencer avec les 30 puis les 40 premiers termes.
(d) Expliquer qualitativement le phnomne.
(e) Plus prcisment, expliquer pourquoi le phnomne est apparu pour ces valeurs
de n.
101

102

1.2 Listes

Exer i e 2 (Matri e d'adja en e d'un graphe) On considre le graphe G suivant, o le

nombre situ sur larte joignant deux sommets est leur distance, suppose entire :

1. Construire la matrice (Mi j )0i ,j 4 , matrice de distances du graphe G, dfinie par : pour
tous les indices i , j , Mi j reprsente la distance entre les sommets i et j , ou encore la
longueur de larte reliant les sommets i et j .
On convient que, lorsque les sommets ne sont pas relies, cette distance vaut 1. La
distance du sommet i lui-mme est, bien sr, gale 0.
2. crire une suite dinstructions permettant de dresser partir de la matrice M la liste
des voisins du sommet 4.
3. crire une fonction voisins, dargument un sommet i , renvoyant la liste des voisins
du sommet i .
4. crire une fonction degre, dargument un sommet i , renvoyant le nombre des voisins
du sommet i , cest--dire le nombre dartes issues de i .
5. crire une fonction longueur, dargument une liste L de sommets de G, renvoyant
la longueur du trajet dcrit par cette liste L, cest--dire la somme des longueurs des
artes empruntes. Si le trajet nest pas possible, la fonction renverra 1.

1.3 Chanes de caractres

Exer i e 3 (Cryptographie) Soit n un entier vrifiant n 26. On souhaite crire un pro-

gramme qui code un mot en dcalant chaque lettre de lalphabet de n lettres.


Par exemple pour n = 3, le dcalage sera le suivant :

Le mot oralensam devient ainsi rudohqvdp.


1. Dfinir une chane de caractres contenant toutes les lettres dans lordre alphabtique
(caractres en minuscule).
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

103
2. crire une fonction de alage, dargument un entier n, renvoyant une chane de caractres contenant toutes les lettres dans lordre alphabtique, dcales de n, comme
indiqu ci-dessus.
3. crire une fonction indi es, darguments un caractre x et une chane de caractres
phrase, renvoyant une liste contenant les indices de x dans phrase si x est une lettre
de phrase et une liste vide sinon.
4. crire une fonction odage darguments un entier n et une chane de caractres phrase,
renvoyant phrase code avec un dcalage de n lettres.
5. Comment peut-on dcoder un mot cod ?

2 Modules

Exer i e 4 (Algorithme du pivot de Gauss ave Numpy)


1. crire une fonction pivot(m,j) qui prend en entre une matrice m (de
taille n p) et
un entier j, et donne en sortie un indice i j tel que |m[i , j ]| = max |m[ j , j ]|, |m[ j +
1, j ]|, . . . , |m[n 1, j ]| .
On rappelle quon choisit comme pivot en mathmatiques un coefficient non nul de la
colonne, mais quen informatique ceci est problmatique, et on prfre donc choisir un
coefficient maximum en valeur absolue.
2. crire une fonction e hange(m,i,j) qui prend en entre une matrice m et deux entiers i et j, et qui change les lignes i et j dans la matrice m.
Remarque : cette fonction ne donne rien en sortie.
3. crire une fonction transve tion(m,i,j, ) qui prend en entre une matrice m, deux
entiers i et j, et un rel , et qui effectue lopration L i L i + c L j .
Remarque : cette fonction ne donne rien en sortie.
4. crire une fonction triangulaire(m) qui prend en entre une matrice m qui est transforme en une matrice triangulaire par lalgorithme de Gauss-Jordan.
5. En dduire une fonction rang(m) qui donne le rang dune matrice m.
6. Pour finir crire une fonction resolution(A,B) qui teste si le systme linaire AX =
B est de Cramer et le rsout dans le cas chant.

3 Algorithmique
3.1 Algorithmique des tableaux/listes et des chanes de caractres

Exer i e 5 (Re her he d'un lment dans une liste) Montrer la terminaison et la correction de lalgorithme de recherche dun lment dans une liste.

Exer i e 6 (Re her he d'un lment dans une liste : variantes) On souhaite rechercher un lment x dans une liste t.

1. crire une fonction re her he_inverse(t,x) qui dtermine le dernier indice i tel
que t[i=x, et renvoie i sil existe, Flase sinon.
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

104
2. crire une fonction re her he_all(t,x) qui dtermine la liste de tous les indices i
tel que t[i=x, et la renvoie (si x nappartient pas t, la fonction doit renvoyer la liste
vide [).

Exer i e 7 (Re her he du maximum dans une liste) Montrer la terminaison et la correction de lalgorithme de recherche du maximum dans une liste.

Exer i e 8 (Re her he du maximum dans une liste : variante)


1. Donner une fonction argmax(t) qui donne le plus petit indice i tel que t[i soit le
maximum de t.
2. Donner une fonction argmax2(t) qui donne la liste de tous les indices i tels que t[i
soit le maximum de t.

3.2 Mthode dEuler

Exer i e 9 (tude de l'os illation d'un pendule par la mthode d'Euler) On consi-

dre un pendule simple oscillant dans un champ de pesanteur constant, compose dune
masse m fixe lextrmit dune tige rigide de masse nulle, tournant sans frottement dans
le plan vertical autour de son extrmit fixe. On note llongation angulaire du pendule, et
on rappelle que vrifie lquation :
g
+ sin() = 0

o est la longueur de la tige et g lacclration de la pesanteur.

On donne = 10 cm, g = 9, 81 m.s 1 et on suppose quinitialement le pendule a une vitesse

nulle et fait un angle de avec la verticale.


2
1. Rsoudre numriquement lquation avec la mthode dEuler. Reprsenter les courbes
de et en fonction du temps.
2. Vrifier la loi de conservation de lnergie, cest--dire que :

est constant au cours du temps.

1 2 2
) g cos()
2

3. Tracer
surun mme graphe les diffrentes orbites de phase, cest--dire les courbes

(t ), (t ) , pour les diffrentes positions initiales (0) choisie dans lensemble


n .
o
k
k 0, 10 .
10
4. Recommencer lexercice en utilisant la fonction odeint du module s ipy.optimize.

Exer i e 10 (Cir uit RLC) On considre un circuit lectrique simple constitu dune source
de tension V , dune rsistance R, dune bobine L et dune capacit C montes en srie
comme le montre le schma suivant.

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

105
Lquation satisfaite par la tension u aux bornes de la bobine est :
d 2u R d u
1
d 2E
+
.
+
.u
=
d t 2 L d t LC
dt2
1. laide de la mthode dEuler, tracer la courbe de la tension aux bornes de la bobine
pour R = 30 , L = 870 mH, C = 630 mF et V (t ) = 10. sin(2. f .t ), avec f = 100 H z, sur
lintervalle de temps [0, 0.4].
2. Faire de mme avec la fonction odeint du module s ipy.

Exer i e 11 (quations de Lotka-Volterra) On veut tudier les quations de Lotka-Volterra


formes dun couple dquations diffrentielles non linaires du premier ordre utilises pour
modliser lvolution des populations de deux espces, lune tant la proie de lautre.

dx

(t ) = x(t ). a b.y(t )
dt

d y (t ) = y(t ). c d .x(t )
dt

x(t ) et y(t ) reprsentent respectivement le nombre dindividus des populations de proies


et de prdateurs. La constante a est la taux de reproduction des proies sans prdateurs. La
constante b est le taux de mortalit des proies du prdateurs. La constante c est le taux de
mortalit des prdateurs en labsence de proie, et d est le taux de reproduction des prdateurs en prsence de proies.
On ne prcise pas lunit de temps et on prendra a = 1.1, b = 0.01, c = 1.2 et d = 0.005.
1. Dans cette question on utilise le schma dEuler.

(a) Tracer sur un mme graphe les courbes x(t ), y(t ) , o x(t ) est le nombre de proies

linstant t et y(t ) le nombre de prdateurs, avec comme conditions initiales x(0), y(0) :
(100, 50) (100, 130) (200, 100) (50, 50)

(b) Traer sur un mme graphe lvolution au cours


du temps
des populations de proies

et de prdateurs pour la condition initiale x(0), y(0) = (50, 50) sur une priode de
20 units de temps.

2. Mme questions en utilisant la fonction odeint du module s ipy.

3.3 Algorithme de Gauss-Jordan

Exer i e 12 (Matri es de Hilbert) Soit H


1
hi j =
pour 1 i , j n.
i + j 1

la matrice de Hilbert dordre n, de coefficients

1. Crer une fonction hilbert dargument n qui renvoie la matrice de Hilbert dordre n
sous forme de tableau numpy.

2. Inverser H10 et faire afficher le coefficient en bas droite. Le rsultat attendu (formel)
est 44 914 183 600. Que constate-t-on ? Pour n = 20, le coefficient correspondant devrait tre 48 722 219 250 572 027 160 000.
On peut dmontrer que la matrice inverse de Hn est coefficients dans Z.
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

106

7.7
7.7
6.
6.

3. Rsoudre le systme H5 X = Y avec Y = 2.1 puis Y = 2.1 .

0.4
0.5
0.
0.
Que peut-on en conclure ?

Exer i e 13 (Matri es tridiagonales) On dfinit la matrice carre dordre n :

.
.

1 . . . .

.. ..
Vn =
.
.

..

..

..
. 1

1 2

Rsoudre crire une fonction resolution(Y) qui donne en sortie la solution du systme
linaire Vn X = Y , en adaptant lalgorithme du pivot de Gauss la forme particulire de Vn
(forme tridiagonale).

4 Lire et crire dans un fichier

Exer i e 14 Objectif : crer un fichier de n lignes remplies alatoirement et reprsentant


les rsultats des lves dune promotion. En rcuprer le contenu, puis calculer la moyenne
des lves par genre.
1. Le fichier des rsultats est constitue de 100 lignes. Chaque ligne est de la forme :

identifiant :20155 note :12.55 sexe : F


Voici comment est rempli le fichier :
(a) Un lve est reprsent par son identifiant : un nombre entier alatoire entre 1000
et 60000.
(b) La note est un nombre flottant choisi alatoirement entre 0 et 20 et arrondi une
dcimale comme 13.1.
(c) Le sexe est dtermin alatoirement : H ou F.
crire une fonction fill qui prend en paramtres un nom de fichier comme
'resultat.txt' et un nombre de lignes n. La fonction remplit le fichier de n lignes
sur le modle ci-dessus (on utilisera le module random).
Voici un exemple dappel :

>>> fill('resultat.txt',100)
2. crire une fonction file2list qui prend en paramtres un nom de fichier rempli
comme resultat.txt, en rcupre le contenu sous forme dune liste dont les lments sont des listes de trois lments :lidentifiant, la note, et le sexe. Exemple :

>>> file2list('resultat.txt')
[[18706, 14.1, 'F',
[53651, 14.3, 'F',
[59644, 13.5, 'H'
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

107
3. crire une fonction averageByGenre qui prend en paramtres une liste de listes, comme
celle retourne par la fonction prcdente et un caractre H (homme) ou F (femme).
La fonction retourne la moyenne des filles, ou la moyenne des garons.

>>> liste=file2list('resultat.txt')
>>> averageByGenre(liste,'H')
13.5
>>> averageByGenre(liste,'F')
14.2

4.1 Requtes SQL

Exer i e 15 (Un peu de gographie) Cet exercice utilise le fichier geographie.sql.


Nous disposons de trois tables. Une table ommunes dont les attributs sont :

num_departement: numro du dpartement ;


nom: nom de la ommune ;
anton : anton de la ommune ;
population_2010: nombre d'habitants lors du re ensement de 2010 ;
population_1999: nombre d'habitants lors du re ensement de 1999 ;
surfa e: surfa e de la ommune en km ;
longitude: longitude du entre de la ommune en GRD
(peu importe l'unit, quand il s'agira de faire des dessins) ;
lattitude: lattitude du entre de la ommune en GRD ;
zmin: hauteur minimum de la ommune par rapport au niveau de l'eau;
zmax: hauteur maximum de la ommune par rapport au niveau de l'eau.
On dispose aussi dune table departements dont les attributs sont num_departement,
num_region et nom, et dune table regions dont les attributs sont num_region et nom (on
rappelle que chaque commune appartient un dpartement, et que chaque dpartement
appartient une rgion).
1. Requtes sans jointure.
(a) Combien dhabitants en France (en supposant que chaque habitant est rattach
exactement une commune, ce qui est peut-tre un postulat faux. . .) ?
(b) Combien de communes sur lle de la Runion ?
(c) Obtenez la liste des dix plus petites communes de France en termes de surface.
Linstruction ORDER BY Attribut LIMIT n affiche les valeurs dattributs par ordre
croissant en se limitant aux n premires valeurs.
(d) Obtenez la liste des dix communes de France les plus peuples.
Linstruction ORDER BY Attribut DESC LIMIT n affiche les valeurs dattributs
par ordre dcroissant en se limitant aux n premires valeurs.
(e) Quelles sont les 5 communes les plus densment peuples de lle de la Runion ?
(f) Obtenez la liste des numros des dpartements, et pour chaque dpartement correspondant, le nombre de communes.
(g) Obtenez la liste des numros des dpartements, et pour chaque dpartement correspondant, la population totale. Ordonnez par population totale dcroissante.
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

108
(h) Combien de communes franaises contiennent la lettre x ou X dans leur nom ?
Linstruction WHERE Attribut LIKE ' haine' teste si la chane de caractre
Attribut est gale ' haine'. Le caractre '%' reprsente une chane quelconque
(mme vide). Le test est insensible la casse (= majuscule ou minusucule)
(i) Combien de communes franaises contiennent les six voyelles a, e, i, o, u, y
(en majuscule ou minuscule) dans leurs noms ?
(j) Existe-t-elle une telle commune sur lle de la Runion ?
(k) Quelles sont les 15 communes de France dont lcart entre laltitude la plus haute,
et laltitude la plus basse, est le plus lev ?
(l) Quelles sont les cinq communes de lle de la Runion o la population a le plus
augment entre 1999 et 2010 ?
(m) Quelles sont les cinq communes de lle de la Runion o la population a le plus
augment en pourcentage entre 1999 et 2010 ?
On affichera le nom des communes, laugmentation effective, et laugmentation
en pourcentage.
2. Jointures deux tables.
(a) Obtenez la liste des dpartements (les noms !), et pour chaque dpartement correspondant, le nombre de communes.
Vous ordonnerez par nombre de communes dcroissant.
(b) Obtenez la liste des dpartements (les noms !) des rgions Auvergne et Aquitaine.
(c) Quelle est la population de chaque dpartement (on veut les noms des dpartements en toutes lettres) ?
Les dpartements seront classs par population dcroissante.
(d) Quelle est la densit de population de chaque dpartement (on veut les noms des
dpartements en toutes lettres et le classement par ordre de densit dcroissante) ?
(e) Obtenez la liste des rgions de France, ainsi que le nombre de dpartements composant la rgion, range par nombre de dpartements dcroissant.
(f) Obtenez la liste des dpartements (les noms !) de plus de 1 200 000 habitants.
(g) Existe-t-il une commune de la rgion Aquitaine, dont le nom contient les six voyelles
'a', 'e', 'i', 'o', 'u', 'y' (en majuscule ou minuscule) ?
Indice : lAquitaine est la rgion numro 2.
(h) Obtenez (sans doublons) la liste des rgions contenant des dpartements dont le
nom commence par c ou C.
3. Jointures trois tables.
(a) Obtenez la liste des rgions de France, et pour chaque rgion, la population totale,
ainsi que le nom et le nombre dhabitants de la commune la plus peuple de la
rgion.
Les rsultats seront affichs par ordre dcroissant de population totale.
(b) Obtenir la liste des rgions (avec le nom en franais), avec la population totale de
chaque rgion, classes par ordre dcroissant de population ?
(c) Densit de population de chaque rgion ?
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

109
(d) Quelles sont les 15 communes de France dont lcart entre laltitude la plus haute,
et laltitude la plus basse, est le plus lev ? Cette fois, prcisez le nom du dpartement et le nom de la rgion pour chaque commune. . .
(e) Combien de communes dans la rgion Basse Normandie ?
4. Sous-requtes.
Pour la clart de la rdaction, on pourra prsenter les requtes sous la forme :

soustable = SELECT ...


SELECT ... FROM soustable WHERE ...
(a) Afficher la (ou les) commune(s) daltitude maximale.
(b) Donner, pour chaque numro de dpartement, le nombre de communes dont la
population en 1999 tait suprieure la population moyenne en 2010.
(c) Afficher le nom du dpartement de mtropole o se trouve la commune daltitude
la plus basse.
Utiliser trois requtes imbriques.
(d) Afficher le nom de la rgion o se trouve la commune daltitude la plus basse.
5. Un peu de dessin. . .

La figure prcdente est une reprsentation graphique des villes de mtropole par
des points dont la couleur dpend de laltitude. Elle a t obtenue avec le programme
suivant :
1
2
3
4

import numpy as np
from math import os , pi
import matplotlib. pyplot as plt
import MySQLdb

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

110
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

Base = MySQLdb . onne t ( host = ' *** ' , user = ' *** ' , passwd = ' *** ' ,db
= ' geographie ')
requete = ' SELECT longitude , latitude , zmax FROM ommunes
WHERE num_departement <= 95 '
Base . query ( requete )
resultat = Base . use_result ()
res = resultat . fet h_row ( maxrows =0)
orr = os (40* pi /180)
Lx =[
Ly =[
Lz =[
for ligne in res :
Lx . append ( float ( ligne [0) )
Ly . append ( float ( ligne [1) )
Lz . append ( float ( ligne [2) )
plt . s atter ( orr * np . array ( Lx ) ,Ly , = Lz )
plt . axis ( ' equal ')
plt . show ()
Base . lose ()

(a) Adapter le programme prcdent pour quil regroupe les communes par canton.
(b) Reprsenter par des points de couleur lattractivit des cantons franais, reprsente par laugmentation relative du nom dhabitants entre 1999 et 2010 (points
placs en fonction de longitude et latitude).
(c) Reprsenter par des points les 5000 plus grosses communes de mtropole (points
placs en fonction de longitude et latitude).

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

Chapitre 4
Exercices de seconde anne
1 Piles

Exer i e 16 (Fon tions sur les piles) Les piles seront modlises par des listes, et on ne

sautorisera comme oprations que les mthodes pop(), append(), ainsi que la comparaison la liste vide [.
On rappelle que les variables de type list sont modifies en place lorsquelles sont donnes
en argument dune fonction.
On pourra effectuer une copie dune pile ainsi : l2 = [ x for x in l (et non l2=l).
Dans les questions suivantes, on nutilisera que les oprations ci-dessus, ainsi que les fonctions programmes dans les questions prcdentes.
1. Ecrire une fonction isempty qui renvoie un boolen indiquant si une pile est vide ou
non.
2. Ecrire une fonction ard qui renvoie le nombre dlments dune pile.
3. Ecrire une fonction peek qui renvoie llment de tte sans le dpiler.
4. Ecrire une fonction lear qui vide une liste en dpilant tous ses lments et ne renvoie rien.
5. Ecrire une fonction dup qui duplique llment du haut de la pile et ne renvoie rien.
6. Ecrire une fonction swap qui permute les deux lments du haut de la pile et ne renvoie rien.
7. Ecrire une fonction permut qui effectue une permutation circulaire des lments dune
pile (pour cela, on pourra utiliser une pile auxiliaire) et ne renvoie rien.
Par exemple [6,4,2,7,9 devient [9,6,4,2,7.

Exer i e 17 (Notation polonaise inverse) La notation polonaise inverse (NPI) permet

dcrire un calcul sans aucune parenthse. Pour cela on place en premier les oprandes, suivi
des oprateurs.
Par exemple, le calcul 32+2*(12-3*(7-2)) se note 32 2 12 3 7 2 - * - * +.
En python le calcul en NPI sera donn sous forme dune liste :

[32,2,12,3,7,2,'-','*','-','*','+'
appele al ul, o les oprandes sont des nombres de type float, et les oprateurs sont des
chanes de caractres. On se limitera aux oprations : addition, soustraction, multiplication
et division.
Pour valuer le calcul, on parcourt utilise une pile auxiliaire pile_aux. On parcourt la liste
reprsentant le calcul de gauche droite, lment par lment :
111

112
si llement est un oprande, on lempile dans la pile pile_aux ;
si llment est un oprateur, on dpile les deux lments du sommet de la pile pile_aux,
on leur applique loprateur, on empile le rsultat sur pile_aux.
A la fin, la pile auxiliaire ne contient plus quun lment qui est le rsultat du calcul. Par
exemple, pour le calcul [32,2,12,3,7,2,'-','*','-','*','+', la variable pile_aux
volue de la faon suivante :

[
[32
[32,
[32,
[32,
[32,
[32,
[32,
[32,
[32,
[32,
[26

2
2, 12
2, 12,
2, 12,
2, 12,
2, 12,
2, 12,
2, -3
-6

3
3, 7
3, 7, 2
3, 5
15

Ecrire une fonction NPI qui prend en entre une liste reprsentant un calcul, et qui value ce
calcul en utilisant lalgorithme prsent ci-dessus.
Pour tester si un lment de la liste est un oprande ou un oprateur, on pourra utiliser une
variable op = ['+','-','*','/'.

Exer i e 18 (Expressions bien parenthses) Pour vrifier si une chane de caractres

est bien parenthse, cest--dire quelle possde autant de parenthses ouvrantes que de
parenthses fermantes et ceci dans le bon ordre, on utilise une pile.
Lalgorithme consiste parcourir la chane de caractres de gauche droite :
chaque fois quon rencontre une parenthse ouvrante, on empile une parenthse
fermante ;
chaque fois quon rencontre une parenthse fermante :
si la pile est vide cest que lexpression est mal parenthse,
sinon on dpile une fois ;
la fin du parcours, il faut que la pile soit vide pour dire que lexpression est bien
parenthse.
Ecrire une fonction parentheses qui prend en entre une chane de caractres, et qui renvoie en sortie un boolen indiquant si lexpression est bien parenthse.

Exer i e 19 (Tri d'une pile)


1. Ecrire une fonction insertion qui prend en entre une pile pile trie dans lordre
croissant et un nombre x, et qui insre x dans la pile de telle sorte quelle soit toujours
trie dans lordre croissant.
Pour cela on pourra utiliser un pile auxiliaire buffer.
2. En dduire un algorithme de tri en place dune pile quelconque.
Encore une fois, on pourra utiliser un pile auxiliaire buffer.
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

113

2 Rcursivit

Exer i e 20 (Coe ients binmiaux)


!
n(n 1) (n k + 1)
n!
n
=
, crire un algorithme
=
1. En utilisant la formule
k! (n k)!
k!
k
itratif qui calcule les coefficients binmiaux.
!
!
!
n 1
n 1
n
, crire une version rcursive
+
=
2. En utilisant la formule de Pascal
k
k 1
k
de cet algorithme.

Exer i e 21 (PGCD)

Si a et b sont deux entiers naturels (avec b 6= 0), et si la division euclidienne de a par b scrit a = bq + r avec r 0, b 1, alors on montre que pgcd(a, b) =
pgcd(b, r ).
En dduire un algorithme itratif et un algorithme rcursif de calcul du pgcd.

Exer i e 22 (Inversion r ursive d'une liste) crire un programme rcursif qui inverse
lordre des lments dune liste.

Exer i e 23 (Suite de Fibona i) La suite de Fibonacci est la suite (u )

n nN

dfinie par :

u 0 = u 1 = 1 et n N, u n+2 = u n+1 + u n
1. crire une fonction itrative qui calcule u n pour n donn..
valuer sa complexit spatiale et temporelle.
2. (a) crire une fonction rcursive qui calcule u n pour n donn..
valuer sa complexit spatiale et temporelle.
(b) Utiliser une variable globale nb_re al uls de type list n + 1 lments, pour
que nb_re al uls[k soit gal au nombre de fois o u k a t calcul lors du calcul
de u n (k 0, n).

3. Pour amliorer la fonction rcursive utiliser une technique de mmosation : utiliser


une variable globale memo type list n + 1 lments, qui stocke les termes de la suite
dj calculs et les rutilise lors des appels rcursifs.
valuer sa complexit spatiale et temporelle.
4. crire une fonction qui calcule u n , laide dune fonction rcursive auxiliaire darguments dentre (n,a,b), qui calcule successivement les couples (u n1 , u n ), pour une
suite (u n )nN telle que u 0 = a, u 1 = b et n N, u n+2 = u n+1 + u n .
valuer sa complexit spatiale et temporelle.
5. Dans cette question on pose u 1 = 0.

u n u n1
1 1
(a) Montrer que, pour tout n N ,
=
.
1 0
u n1 u n2
(
2
u 2n1 = 2u n1 u n u n1
En dduire que, pour tout n N ,
2
u 2n = u n1
+ u n2

(b) En dduire une fonction rcursive qui calcule le couple (u n1 , u n ) pour n donn.
valuer sa complexit spatiale et temporelle.

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

114

Exer i e 24 (Tours de Hano) Le problme des tours de Hano est un jeu de rflexion

imagin par le mathmaticien franais douard Lucas, et consistant dplacer des disques
de diamtres diffrents dune tour de dpart une tour d arrive en passant par une
tour intermdiaire , et ceci en un minimum de coups, tout en respectant les rgles suivantes :
on ne peut dplacer plus dun disque la fois,
on ne peut placer un disque que sur un autre disque plus grand que lui ou sur un
emplacement vide.

1. Proposer alors une fonction rcursive hanoi(n,dep,aux,arr) qui affiche les dplacements effectuer pour dplacer n disques du piquet dep vers le piquet arr, en utilisant le piquet intermdiaire aux.
2. Combien de dplacements sont ncessaires pour que les n disques passent tous du
piquet de dpart au piquet d arrive ?
3. Selon la lgende imagine par E. Lucas, le jeu a commenc en 1500 avant J.C., dans
un temple Hano, avec 64 disques dor, et la fin du monde arrivera quand le jeu se
termine ( raison dune seconde par dplacement). Est ce vrai ? (on prendra 14 milliards dannes comme ge de lunivers)

Exer i e 25 (Sudoku) Dans cette exercice, on se propose de rsoudre les grilles de sudoku

de manire rcursive. Une grille de sudoku sera represente par une matrice 9 9 comme
suit :

1. crire une fonction re her he_zero(M) qui renvoie les coordonnes de la premire
case non remplie de la grille M, et qui renvoie [10,10 si toutes les cases sont remplies.
2. crire une fonction test_ligne_ olonne(M,i,j,val) qui vrifie si on peut mettre
la valeur val dans la case [i,j de la grille M en vrifiant que val nest pas dj dans
la ligne i ou la colonne j.
Cette fonction renverra True ou False.
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

115
3. crire une fonction test_sous_ arre(M,i,j,val) qui fait la mme chose mais vrifie si val nest pas prsent dans le sous-carr qui contient la case [i,j.
4. Complter le code ci-dessous pour crer une fonction qui vrifie si on peut mettre la
valeur val dans la case [i,j de la grille M (vous navez le droit qu une ligne de code.)
1
2

def test_ ase (M ,i ,j , val ):


return ...

5. laide des fonctions prcdentes, crire une fonction rcursive sudoku qui va rsoudre la grille de sudoku en testant toutes les valeurs possibles pour chaque case.
La fonction se contentera dafficher la grille solution. Sil y a plusieurs solutions on les
affichera toutes (bien que dans la vraie rgle cette grille serait dclare insoluble)

Exer i e 26 (Algorithme de Hrner) Soit P = a

nX

lynme, et x0 un nombre rel.

+ an1 X n1 + + a0 R[X ] un po-

1. crire un programme naf qui calcul P (x0 ).


2. La mthode de Hrner consiste amliorer ce rsultat en effectuant le calcul comme
suit :
P (x0 ) = ((. . . ((an x0 + an1 )x0 + an2 )x0 + . . . )x0 + a1 )x0 + a0 .
Proposer une version itrative et une version rcursive de cet algorithme.

3. Comparer les complexits ces algorithmes (on ne prendra en compte que les multiplications).

Exer i e 27 (Re her he d'un ara tre dans une hane)


1. crire une fonction rcursive sear h( ,s) qui renvoie un boolen indiquant si c est
dans s.
2. Amliorer sear h pour quelle renvoie la premire position du caractre dans la chane,
sil y est, et le nombre -1 sinon.

Exer i e 28 (Cal ul d'un dterminant)


1. crire un programme rcursif qui calcule le dterminant dune matrice laide du
dveloppement par rapport la premire colonne.
2. Montrer que la complexit est (n!).

3. Proposer un meilleur algorithme de calcul de dterminant.

Exer i e 29 (Serpent vietnamien) Le but du jeu est de remplir les cases de la grille suivante, avec des chiffres de 1 9 (quil ne faut utiliser quune fois chacun), en suivant lordre
des oprations, de faon obtenir 66 comme rsultat final :

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

116
1. crire une fonction rcursive qui prend en entre une liste l de nombres, et donne
en sortie la liste de toutes les permutations de cette liste (donc si l est une liste de n
nombres, la liste donne en sortie est une liste de n! listes).
2. En dduire un programme Python qui dtermine toutes les solutions au jeu du serpent vietnamien (en sortie on pourra se contenter de nafficher que le nombre total
de solutions).

Exer i e 30 (Algorithme de Strassen) Dans cet exercice, nous allons voir plusieurs fa-

ons de programmer le produit de deux matrices carres dordre k. Pour manipuler les matrices on utiliser le module numpy.
1. crire un algorithme qui effectue le produit matriciel grce la formule appris dans
le cours de mathmatiques. valuer sa complexit.
2. On va essayer damliorer les performances.
(a) crire une fonction logdeux(k) qui prend en entre un entier naturel k, et renvoie
en sortie le plus petit entier naturel n tel que k 2n .

(b) Crer une fonction newsize(m) qui prend en paramtres une matrice carre m, et
retourne une nouvelle matrice qui est une copie de m laquelle on ajoute des zros
pour en faire une matrice 2n 2n .

(c) Crer une fonction one2four(m) qui prend en paramtre une matrice carre 2n
2n et renvoie les 4 sous-matrices usuelles de tailles 2n1 2n1 .

(d) Crer une fonction four2one((a,b, ,d)) inverse de la prcdente.

(e) En utilisant ce qui prcde, crer une fonction rcursive produit(m1,m2) qui prend
en paramtres deux matrices carres de mme dimensions2n 2n et les dcoupe
en blocs comme ici :


A B
A B

m1 =
et
m2 =
C D
C D
La fonction calcule ensuite rcursivement le produit m 1 m 2 en utilisant le produit
par blocs vu en cours.
(f) crire le programme principal mult(m1,m2) qui prend en entre deux matrices
carres m1, m2, les redimensionne en matrices de taille 2n 2n , effectue leur produit matriciel avec la fonction produit, puis affiche le rsultat sans les lignes et
colonnes de zros ajouts par la fonction newsize.
(g) Quelle est la complexit de cet algorithme ?
(h) Pour diminuer cette complexit, Volker Strassen a mis en place la mthode suivante en 1968. Pour effectuer le produit m 1 m 2 , on pose :
X 1 = (A + D)(A + D )
X 2 = (C + D)A

X 3 = A(B D )

X 4 = D(C A )
X 5 = (A + B)D

X 6 = (C A)(A + B )

X 7 = (B D)(C + D )

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

117
et vrifie alors facilement que :

X1 + X4 X5 + X7
X3 + X5

m1m2 =
X2 + X4
X1 X2 + X3 + X6
Transformer la fonction mult(m1,m2) en une fonction strassen(m1,m2) qui utilise la mthode de Strassen.
Quelle est la complexit de ce nouvel algorithme ?

3 Tris

Exer i e 31 (Tri bulle)


1. On considre une liste l de n nombres.
On la parcourt de gauche droite, en comparant chaque fois llment avec le suivant : sils ne sont pas dans lordre croissant, alors on les permute.
la fin du parcours de la liste, quelle particularit a la liste l ?
2. En dduire un nouvel algorithme de tri.
3. Dterminer sa complexit en moyenne, dans le pire des cas, et dans le meilleur des
cas.
On ne sintressera quau nombre de comparaisons.

Exer i e 32 (Tri par sle tion)


1. crire une fonction qui dtermine le plus petit lment dune liste de nombres et le
place en premire position.
2. En dduire une fonction (rcursive ou non) qui trie en place une liste de nombres.
3. Dterminer sa complexit en moyenne, dans le pire des cas, et dans le meilleur des
cas.
On ne sintressera quau nombre de comparaisons.

Exer i e 33 (Re her he de la mdiane) La mdiane dun ensemble de n nombres est

le nombre qui est plus grand que la moiti de ces nombres, et plus petit que lautre moiti
de ces nombres. Autrement dit, cest le nombre qui se trouve au milieu du tableau si on trie
celui-ci. Pour une liste trie de 2N + 1 nombres cest donc le (N + 1)-ime nombre, pour une
liste trie de 2N nombres, une mdiane est nimporte quel nombre compris entre le N -ime
et le (N + 1)-ime.

1. Proposer une fonction mediane_tri qui calcule une mdiane dune liste en utilisant
un algorithme de tri.

Pour une liste quelconque, le mieux quon puisse faire est alors en O(n logn), mme si, dans
certains cas, le tri insertion donne une complexit en O(n).
On ne va donc pas trier la liste, juste chercher sa mdiane.
On implante ici la mthode Quickselect de Hoare qui a une complexit moyenne en O(n),
O(n 2 ) dans le pire des cas.
2. Implmenter la fonction partition(l,g,d) du cours, qui transforme la sous-liste
l[g:d de telle sorte qu gauche de la valeur l[g se trouve les lments plus petits
et droite les lments plus grands. En sortie elle donne la position du pivot l[g.
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

118
3. On crit une fonction rcursive sele t_re (l,g,d,k) qui prend en paramtres une
liste l , deux indices gauche et droite, g , d ainsi quun indice k.
Cette fonction retourne le k-ime lment de la liste dans le classement croissant
(sans trier la liste).
Pour ce faire, on partitionne dabord la portion entre g et d de la liste et on note p,
lindice du pivot (donn par lappel partition(l,g,d)) :
(a) Si p = k, on a llment k de la liste.

(b) Si p < k, llment k est droite de p, on appelle sele t_re sur la portion droite
du pivot.
(c) Sinon, le k-ime lment est gauche de p, on appelle sele t_re sur la portion
de la liste gauche du pivot.
La close darrt est donne par le cas o la sous-liste na quun seul lment.
Comme pour le tri rapide en place, on crit ensuite une fonction sele t(l,k) qui
appelle sele t_re pour obtenir le k-ime lment du tableau dans le classement
croissant.
Tester sur des exemples et remarquer que la liste na pas besoin dtre entirement
trie.
4. Pour une liste l tri de longueur N , la mdiane est llment plac proximit immdiate de lindice N /2 (suivant la parit du nombre dlments) :
(a) si N est impair, la mdiane est t [(N 1)/2],

(b) si N est pair (et la liste non vide), la mdiane est nimporte quel nombre strictement compris entre t [N /2 1] et t [N /2].

En gardant ceci en mmoire, et en utilisant la fonction sele t, proposer une nouvelle


implmentation de la fonction mediane.
Pour cela faites attention au fait que si la liste l est trie, lappel sele t(l,k) ne
donne pas l[k mais l[k-1 (car les listes sont indexes partir de 0).

4 Autres
4.1 Stganographie
La stganographie est lart de la dissimulation : son objet est de faire passer inaperu un
message dans un autre message. Elle se distingue de la cryptographie, art du secret , qui
cherche rendre un message inintelligible autre que qui-de-droit. Pour prendre une mtaphore, la stganographie consisterait enterrer son argent dans son jardin l o la cryptographie consisterait lenfermer dans un coffre-fort cela dit, rien nempche de combiner
les deux techniques, de mme que lon peut enterrer un coffre dans son jardin.
On peut utiliser Python pour cacher une image dans une autre. Commenons par quelques
notions sur les images en informatique :
une image est une reprsentation visuelle de quelque chose ;
cette reprsentation est dcoupe en lments carrs appels pixels (picture element),
chaque pixel tant compos dune seule couleur ;
un cran possde un nombre fixe de pixels dfini comme tant le produit du nombre
de pixels en largeur par le nombre de pixels en hauteur (cest la dfinition dcran, par
exemple : 1024 768).
On peut dfinir la taille et la dimension dune image :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

119
Taille dune image. Espace mmoire quoccupe un fichier image sur le disque dur,
exprime en octets. Exemple : 250 Ko.
Dimensions dune image. Espace visuel quoccupe une image sur lcran, reprsentes par un couple de valeurs longueur largeur. Lunit utilise ici sera le pixel.
Exemple : 360 200.

Pour reprsenter un couleur, on utilise une combinaison de couleurs primaires. Il existe plusieurs faons de le faire : ce sont les modes colorimtriques.
Nous nous intresserons ici au mode RGB (Red-Green-Blue) ou RVB (Rouge-Vert-Bleu). Ce
mode attribue chaque pixel une intensit de rouge, vert et bleu. Cette intensit est un
nombre compris entre 0 (intensit nulle) et 255 (intensit maximum). On peut reprsenter
de cette faon 2563 = 16777216 couleurs diffrentes !

Chaque intensit tant une valeur comprise entre 0 et 255, il faut donc 8 bits (1 octet) pour
coder une intensit en binaire (28 = 256).

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

120
Nous allons cacher notre image secrte (hidden image) lintrieur de chaque pixel de notre
image originale (cover image). Pour simplifier, les dimensions de ces 2 images seront identiques. Chaque pixel de notre image originale sera lgrement modifi : plus prcisment
nous allons modifier les bits de poids faible de chaque pixel. Cest la mthode LSB : Least
Significant Bit.
Sur lexemple ci-dessous, les composantes R,G et B de ces deux couleurs diffrent de 2.
Pourtant loeil nu on ne voit pas la diffrence.

Pour cacher un pixel B dans un pixel A, nous allons donc remplacer les 4 bits de poids faible
du pixel A par les 4 bits de poids fort du pixel B.
Par exemple si :

R : 39 = 0010 01112

2
A G : 88 = 0101 1000

B : 165 = 1010 01012

et

on remplace le pixel A par le pixel modifi :

R : 62 = 0011 11102

2
B G : 73 = 0100 1001

B : 75 = 0100 10112

R : 0010 00112 = 35

2
A G : 0101 0100 = 84

B : 1010 01002 = 164


ce qui transforme

en

, le pixel cach tant

Inversement pour retrouver limage cach, on fait lopration inverse : on extrait les bits de
poids faible du pixel reu et on complte par quatre 0.
Dans lexemple prcdent, le pixel A devient :

R : 0011 00002 = 48

2
B G : 0100 0000 = 64

B : 0100 00002 = 64
donc le pixel

, une fois cach, est rcupr comme le pixel

Une image de dimension p n sera reprsente par un tableau numpy trois dimensions
n p 3 (noter linversion de n et p). La troisime dimension correspond la couleur (rouge,
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

121
vers ou bleu, indice 0, 1 ou 2). Les valeurs stockes dans ce tableau sont des entiers entre 0
et 255 : on imposera donc ces valeurs dtre du type uint8 de numpy (entiers non signs
cods sur 8 bits).
Dans la suite on suppose quon a import le module numpy.
1. La fonction bin donne la reprsentation binaire dun entier. Les entiers entre 0 et 255
sont reprsents sous la forme dune chane de caractre '0b...' composs de 3 10
caractres.
Pour appliquer lalgorithme de stganographie, on a besoin quil soient reprsents
par des chanes de 8 caractres, sans le prfixe '0b' (les premiers caractres tant
ventuellement nuls).
(a) En utilisant la concatnation mot1+mot2 et lextraction mot[n:p (o n et p peuvent
tre ngatifs), crire une ligne de commande qui transforme une chane de 3 8
caractres 0b... en une chane de 8 caractres exactement, sans le prfixe 0b, les
premiers caractres tant ventuellement nuls.
Par exemple '0b10100' doit devenir '00010100'.
(b) En dduire une fonction tab2bin(tableau) qui prend entre une variable tableau
qui est un tableau numpy de dimensions n p 3 dentiers de type uint8, les transforme en binaire avec la fonction bin, puis les met sous la forme de chanes de 8
caractres.
On rappelle que si f est une fonction dfinie sur les nombres, alors ve torize(f)
donne une fonction dfinie sur les tableaux numpy.
De plus, tableau.shape donne [n,p,3.
(c) Inversement, ces chanes de 8 caractres peuvent tre transformes en entiers avec
la fonction int(.,2).
crire une fonction bin2tab(tableau) qui prend entre un tableau numpy de
chanes de 8 caractres reprsentant en binaire des entiers entre 0 et 255, cre
un tableau numpy appel tableau2 dont les valeurs sont de type uint8, puis affecte chaque case de tableau2 lentier reprsent par la case correspondant de
tableau. En sortie cette fonction retournera la variable tableau2.
On rappelle que zeros((n,p,3),dtype=uint8) cre un tableau numpy de dimensions n p 3, dont les valeurs sont de type uint8.

2. (a) Donner une fonction steganographie(tab_image,tab_se ret) qui :


prend en entre deux tableaux numpy de dimensions np3, appels tab_image
et tab_se ret, dont les cases sont des chanes de 8 caractres ;
cre un tableau numpy de mme dimension, dont les cases sont du type S10
(chanes de 10 caractres), appel tab_en ode ;
applique chaque case de tab_image et tab_se ret lalgorithme de stganographie (pour cacher tab_se ret dans tab_image), et enregistre le rsultat
dans la case correspondante de tab_en ode.
En sortie la fonction doit retourner le tableau tab_en ode.
On rappelle que zeros((n,p,3),dtype='|S10') cre un tableau numpy de dimensions n p 3, dont les valeurs sont de type S10.
(b) Donner une fonction steganographie_inverse(tab_image) qui :
prend en entre un tableau numpy de dimensions n p 3, appel tab_image,
dont les cases sont des chanes de 8 caractres ;

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

122
cre un tableau numpy de mme dimension, dont les cases sont du type S10
(chanes de 10 caractres), appel tab_de ode ;
applique chaque case de tab_image lalgorithme de dcodage et enregistre
le rsultat dans la case correspondante de tab_de ode
En sortie la fonction doit retourner le tableau tab_de ode.
Nous allons maintenant utiliser le module matplotlib.pyplot pour manipuler des images
au format PNG (attention ce dernier point est indispensable). Si image.png est le nom du
fichier (donc une chane de caractres), les commandes :

tableau_float=imread('image.png')
tableau_int=uint8(255*tableau_float)
cre le tableau numpy de dimensions n p 3 associ (pour image.png de dimensions p n),
sous le nom tableau_int.
Ensuite imshow(tableau_int) permet de visualiser limage.
Inversement imsave('image2.png',tableau_int) cre limage PNG associe au tableau
et lenregistre sous le nom image2.png.
3. (a) Donner une fonction image_en ode(masque, se ret) qui :
prend en entre deux noms dimages masque et se ret qui sont des chanes
de caractres ;
cre les tableaux dentiers numpy tab_masque et tab_se ret associs ;
les transforme en tableaux de chanes de caractres comme indiqu la question 1. ;
leur applique lalgorithme de stganographie et enregistre le rsultat dans une
variable tab_en ode ;
transforme ce tableau en tableau dentiers comme la question 1. et enregistre
le rsultat dans une variable en ode ;
affiche limage associe et lenregistre dans le nouveau fichier en ode.png.
Cette fonction ne renvoie rien en sortie.
(b) Donner une fonction image_de ode(image) qui :
prend en entre un nom dimage image qui est une chane de caractres ;
cre le tableau dentiers numpy tab_image associ ;
le transforme en tableaux de chanes de caractres comme indiqu la question 1. ;
lui applique lalgorithme de dcodage et enregistre le rsultat dans une variable
tab_de ode ;
transforme ce tableau en tableau dentiers comme la question 1. et enregistre
le rsultat dans une variable de ode ;
affiche limage associe et lenregistre dans le nouveau fichier de ode.png.
Cette fonction ne renvoie rien en sortie.

4.2 Algorithme de Dijkstra


Lalgorithme de Dijkstra permet de dterminer le plus court chemin dun point un autre.
Les circuits possibles seront modliss par un graphe orient (les chemins peuvent parfois
ntre parcouru que dans un seul sens) et pondr (chaque chemin comporte un temps de
trajet). Prenons par exemple le graphe suivant o on cherche le plus court temps de trajet de
AB :
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

123

Si on veut essayer tous les chemins possibles, on arrive trs vite un temps colossal, et
calculer un itinraire sur un GPS pourrait prendre plus de 1030 annes !
Lide cl de Dijkstra est la suivante : si un chemin optimal de A vers B apsse par un sommer
X , alors la partie de ce chemin de A X est encore un itinraire optimal de A vers X . En effet,
sil existait un chemin plus rapide de A vers X , il permettrait de rduire le trajet total de A
vers B.
On associe alors, chaque sommet X (autre que A) son prdecesseur p(X ), cest--dire le
sommet immdiatement prcdent dans le chemin optimal menant de A X . Dans lexemple
ci-dessus, on a p(B) = H, p(H) = G, et ainsi de suite jusqu p(C ) = A (le chemin optimal est
indiqu en vert).
La fonction p permet de reconstruire, de proche en proche, pour chaque sommet X , un
chemin optimal de A vers X . On note t (X ) le temps de parcours correspondant.
Au dpart, on ne dispose pas des valeurs dfinitives de t (X ) et p(X ) : on ne se contente que
de valeurs provisoires, respectivement (X ) et (X ), donnes par le meilleur itinraire de A
vers X actuellement connu. Ces valeurs vont voluer, par amliorations successives, vers les
valeurs dfinitives.
Appelons lensemble des sommets du graphe pour lesquels on sait que les fonctions t et p
ont atteint leur valeurs dfinitives. Lalgorithme consiste faire grossir de proche en proche
en lui ajoutant, chaque itration, un nouveau sommet.
Voici comment :
Initialisation :
au dpart = A avec (A) = t (A) = 0 (le trajet optimal de A vers A prend un temps
nul, par un chemin form de zro arte)) ;
pour les sommets X diffrents de A, on ne connat pas de chemin et on initialise
donc (X ) + en convenant que, tant que (X ) naura pas de valeur finie, (X )
ne sera pas dfini.
Une itration se fait en deux tapes :
Dabord, on considre toutes les artes U V dont lorigine U est dans et lextrmit v est lextrieur de Ome g a. Pour chacune delles, on connat un trajet
optimal de A vers U (car U est dans ). En prolongeant ce trajet jusqu V on a un
temps total de parcours gal t (U ) + (U V ), o (U V ) est le temps de parcours
de U V (donn par le graphe).
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

124

Si cette somme est infrieure (V ), ce trajet pourrait tre optimal vers V , et on le


retient en posant (V ) = t (U ) + (U V ) et (V ) = U .
Ces valeurs restent toujours relatives au meilleur itinraire actuellement connu
(notons que V peut tre atteint par plusieurs sommets. . .).
Dans une seconde tape, on choisit parmi les sommets X extrieurs Ome g a et
tels que (X ) < + (et o (X ) est donc dfini), un X qui minimise (X ). Le trajet
optimal de A vers (X ) (qui est dans ) suivi de larte joignant (X ) X est alors
un trajet optimal vers X .
En effet, sil existait un trajet plus rapide, en notant Y le prdcesseur dans ce dernier trajet, Y devrait tre dans (car Y a d, lors dune tape prcdente, tre
inclus dans ), ce qui contredit la dfinition de X ((X ) ne serait pas minimal).
Le sommet X ainsi trouv est ensuite ajout lensemble , et on pose p(X ) =
(X ) et t (X ) = (X ).
Ceci termine litration.
On recommence alors avec le nouvel ensemble grossi qui, de proche en proche,
finira aussi par contenir le point B qui nous intresse (sauf larbre rend inacessible le
point B partant de A), marquant la fin de lalgorithme.
Lalgorithme de Dijkstra fournit litinraire optimal de A vers B ainsi que les itinraires optimaux pour tous les points qui, partant de A, sont plus rapides atteindre que B.
Donnons les premires tapes sur lexemple de lnonc :
Initialisation. On initialise = {A}, t (A) = 0 et (X ) = + pour tout sommet X autre
que A.
Premire itration. On considre les artes ayant leur origine en A, cest--dire AC ,
AL, AM et AN , ce qui nous amne poser :
(C ) = 3, (L) = 4, (M) = 3, (N ) = 3
(C ) = (L) = (M) = A

Parmi ces quatre sommets (C , L, M et N ), il faut en trouver un minimisant le temps


de parcours : C par exemple.
On pose donc t (C ) = 3 et p(C ) = A.
Continuons lalgorithme avec = {A,C }, t (A) = 0, t (C ) = 3, p(C ) = A, (L) = 4, (M) =
3, (N ) = 3 et les autres +, (L) = (M) = (N ) = A.
Seconde itration. On considre les artes ayant leur origine en A ou C , cest--dire
AL, AM, AN , C D et C M.
La premire tape de litration conduit poser (D) = 6, (D) = C .
Choisissons M. On pose donc t (M) = 3, p(M) = A.
Poursuivons donc lalgorithme avec = {A,C , M}, t (A) = 0, t (C ) = 3, t (M) = 3, (D) =
6, (L) = 4, (N ) = 3 et les autres +, (L) = (N ) = A et (D) = C .
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

125
Troisime itration. On considre les artes AL, AN , C D et ML. Les deux tapes
conduisent = {A,C , M, N }, t (N ) = 3 et p(N ) = A.
Quatrime itration. Les artes considrer sont AL, C D, ML, N P et N R. Le point
suivant tre englob dans est L ave t (L) = 4 et p(L) = A.
Nous modliserons le graphe orient pondr par sa matrice des distances : si il y a n sommets numrots de 0 n 1, on dfinit une matrice A dordre n (avec les lignes et colonnes
numrotes partir de 0 comme en Python) telle que ai j donne le temps de parcours du
sommet i vers le sommet j . Si on ne peut aller de i vers j , on pose ai j = 0.
Les matrices seront reprsents en Python par des listes de listes.
1. (a) crire la matrice des distances du graphe donn en exemple.
(b) Elle est donne dans le fichier Exemple.txt. crire un script Python qui permet
de lire le fichier et denregistrer la matrice dans une variable arbre (commencer
par visualiser le fichier pour comprendre sa strucutre)
2. crire une fonction ind_min(liste,omega) qui prend en entre :
une liste liste de n nombres ;
une liste omega de nombres entre 0 et n 1 ;
et donne en sortie lindice X qui minimise liste[k pour tous les k pris lextrieur
de omega.
3. Dans cette question, on va crire la fonction principale dijkstra(arbre,A,B,sommets) :
arbre est la matrice des distances ;
A est lindice du sommet de dpart ;
B est lindice du sommet darrive ;
sommets est la liste des noms de sommets : sommets[k donne le nom du somme
numro k.
En Python il existe un flottant qui reprsente + : infini=float('inf').
(a) Initialiser les variables suivantes :
n comme le nombre de sommets ;
Omega comme une liste ne contenant que le sommet A ;
tau comme une liste de n nombres gaux infini ;
t comme une liste de n zros ;
pi et p comme deux listes de n fois None.

(b) crire une boucle while effectuant lalgorithme de Dijkstra : la fin t[B donne
le temps de parcours optimal de A vers B, et la trajet optimal est contenu dans la
liste p.
(c) crire la fin du programme qui permet de rcuprer dans p le trajet optimal et
retourne en sortie de la fonction :
le parcours optimal sous forme dune liste de noms de sommets ;
le temps de trajet optimal sous forme dun flottant.
4. Tester avec lexemple donn dans lnonc.
5. Que fait lalgorithme si B nest pas accessible depuis A dans le graphe propos ?
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

126

4.3 quation de la chaleur


On tudie les transferts thermiques dans le mur dune maison. La temprature lintrieur
de la maison est constante dans le temps et gale Tint = 20 C . Aux temps ngatifs (t <
0), la temprature extrieure est gale Text1 = 10 C . t = 0, elle chute brusquement
Text2 = 10 C et elle reste gale cette valeur aux temps positifs (t > 0). On souhaite tudier
lvolution du profil de temprature dans le mur au cours du temps.

Le mur a une paisseur e = 40 cm. Les proprits physiques du mur sont constantes : conductivit thermique = 1, 65 W.m 1 .K 1 , capacit thermique massique c p = 1 000 J .kg 1 .K 1 ,
masse volumique = 2 150 kg .m 3 .
On suppose que la temprature dans le mur T ne dpend que du temps t et de la coordonne
x. Lquation qui dcrit lvolution de cette temprature est :
=

T 2 T
=
t
x 2

(1)

o = c p /. Les conditions aux limites sont :


T (0, t ) = Ti nt
T (e, t ) = Text2
Text1 Ti nt
T (x, 0) =
.x + Ti nt
e

pour tout t > 0


pour tout t > 0

Pour rsoudre le problme de manire numrique, on discrtise lespace et le temps. On divise lintervalle [0, e], reprsentant lpaisseur du mur, en N +2 points, numrots de 0 N +1,
rgulirement espacs de x. Cette division est appele discrtisation . La distance x est
appele le pas despace . lintrieur du mur (frontires intrieure et extrieure exclues)
se trouvent donc N points. On cherche obtenir la temprature en ces points particuliers
chaque instant.

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

127
On remarquera que x =

e
et, pour i 0, N + 1 : xi = i x.
N +1

Le temps est discrtis en I t M ax intervalles de dure t et on ne sintresse au profil de


temprature quaux instants particuliers tk = k.t . Lintervalle lmentaire de temps t est
appel le pas de temps .
On notera Tik la temprature T (xi , tk ), value au point dabscisse xi linstant tk . Ainsi le
k
vecteur (T0k , T1k , . . . , T N+1
) reprsente le profil de temprature dans le mur linstant tk .
1. Mthode utilisant un schma explicite.
(a) Justifier que lquation (1) peut scrire sous la forme :
Tik+1 = r.Tik1 + (1 2r ).Tik + r.Tik+1 pour tout i 1, N
T0k = Ti nt
k
T N+1
= Text2
o on a pos r =

t
, et k N.
.(x)2

Cette quation est appele schma dEuler explicite. Si on connat la temprature en


tous les points x1 , x2 , . . . , x N linstant tk , on peut calculer grce elle la temprature
en tous les points linstant ultrieur tk+1 .
On veut laborer une fonction s hema_expli ite(T0,alpha,e,Delta_t,Tint,Text2)
permettant de calculer la temprature en chaque point au cours du temps. La variable
T0 est un vecteur de dimension N , contenant les valeurs de la temprature aux points
de discrtisation linstant initial. Les autres variables dentre sont les constantes dfinies dans lnonc. Au sein de la fonction, un algorithme calculera itrativement la
temprature avec un nombre maximal ditrations ItMax=\numprint{2000}. En sortie de la fonction, on rcuprera le nombre ditrations rellement effectues nbIter,
et une matrice T_tous_k de dimensions N I t M ax. Chaque colonne de cette matrice contient le vecteur Tk dont les lments sont les valeurs de la temprature aux N
points x1 , . . . , x N (points lintrieur du mur) linstant k :

T1k
T k
2
Tk = .
..

T Nk

et

T1
11
T
Tt ousk = 2
...
T N1

T12
T22
...
T N2

. . . T1k
. . . T2k
... ...
. . . T Nk

. . . T1k1 T1k

. . . T2k1 T2k

...
...
...
. . . T Nk1 T Nk

On souhaite arrter le calcul lorsque la temprature ne varie presque plus dans le


temps. Dans ce but, on valuera la norme de Tk Tk1 chaque itration.
(b) crire la fonction s hema_expli ite(T0,alpha,e,Delta_t,Tint,Text2) en suivant les indications suivantes :
dfinir les constantes ItMax, N, Delta x et r ;
crire un test qui affiche une alerte si r 0.5 (on admet que dans ce cas le
schma ne converge pas vers la solution) ;
crer avec la matrice T_tous_k de dimensions N I t M ax en la remplissant de
zros ;
remplacer la premire colonne de T_tous_k par T0 ;
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

128
calculer le profil de temprature linstant k = 1 (ie t = t ) en disinguant les
cas i = 1, 2 i N 1 et i = N , et laffecter la deuxime colonne de T_tous_k ;
laborer une boucle permettant de calculer itrativement le profil de temprature aux instants tk = k.t (avec k 2), boucle interrompue lorsque le la
norme de Tk Tk1 deviendra infrieur 102 ou lorsque le nombre ditrations atteindra la valeur ItMax ;
retourner en sortie le nombre ditrations nbIter et la matrice T_tous_k.

(c) Pour N = 60 et t = 25 s, faire afficher :


le temps en heures au bout duquel le rgime permanent est tabli ;
sur un mme graphique le profil de temprature en fonction de x tous,les 100
pas de temps.

Le rgime permanent est atteint au bout de 12.4375 heures.

2. Mthode utilisant un schma implicite.


Le schma explicit ne converge que si le pas de temps t est suffisamment faible par
rapport au pas despace Delta x. Si lon souhaite effectuer un calcul pour un temps
physique long, beaucoup ditrations seont ncessaires et le temps de calcul sera trs
long. Cest pourquoi on prfre dautres types de schmas appels implicites.
La drive partielle seconde par rapport x de la temprature sera value au point
dabscisse xi et linstant k + 1 :
2 T
2 T
(x,
t
)

(xi , tk+1 )
x 2
x 2

et la drive partielle par rapport t est value au point dabscisses xi linstant k :


T
T
(x, t )
(xi , tk+1 )
t
t
(a) Justifier que lquation (1) peut alors scrire sous la forme :
Tik = r.Tik+1
+ (1 + 2r ).Tik+1 r.Tik+1
pour tout i 1, N
1
+1
k
T0 = Ti nt
k
T N+1
= Text2
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

129
o on a pos r =

t
, et k N.
.(x)2

Cette quation est appele schma implicite car la temprature linstant t k est exprime en fonction de la temprature linstant ultrieur tk+1 .
Le systme dquations ainsi obtenu peut tre crit sous la forme :
M.Tk+1 = Tk + r.v
o M est une matrice carre N N , et v est un vecteur de taille N faisant intervenir les
conditions aux limites.
(b) Prciser lexpression de la matrice M et lexpression du vecteur v.
chaque pas de temps, il faut inverser le systme matriciel :
M.Tk+1 = Tk + r.v
pour obtenir Tk+1 partir de Tk .
Pour cela, on va utiliser lalgorithme de Thomas qui permet de rsoudre un systme
matriciel tridiagonal de la forme :
M.u = d
o M est une matrice de dimensions N N tridiagonale, et u et d des matrices colonnes de dimension N .
Dans cet algorithme, on calcule dabord les coefficients suivants :
c1 =
ci =

c1
b1

ci
b i ai ci 1

et
d 1 =
d i =

d1
b1
d i ai d i 1
b i ai ci 1

pour i = 2, 3, . . ., N 1

pour i = 2, 3, . . ., N

Les inconnues u 1 ,u 2 , . . . , u N sont alors obtenues par les formules :

uN = dN

u i = d i ci u i +1 pour i = N 1, N 2, . . . , 2, 1

(c) En utilisant lalgorithme de Thomas, crire une fonction Cal Tkp1(M,d) qui permet de calculer le vecteur u.
(d) crire la fonction s hema_impli ite(T0,alpha,e,Delta_t,Tint,Text2) en suivant les indications suivantes :
dfinir les constantes ItMax, N, Delta x et r ;
crer avec la matrice T_tous_k de dimensions N I t M ax en la remplissant de
zros ;
remplacer la premire colonne de T_tous_k par T0 ;
calculer le profil de temprature linstant k = 1 (ie t = t ) en disinguant les
cas i = 1, 2 i N 1 et i = N , et laffecter la deuxime colonne de T_tous_k ;
PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

130
laborer une boucle permettant de calculer itrativement le profil de temprature aux instants tk = k.t (avec k 2), boucle interrompue lorsque le la
norme de Tk Tk1 deviendra infrieur 102 ou lorsque le nombre ditrations atteindra la valeur ItMax ;
retourner en sortie le nombre ditrations nbIter et la matrice T_tous_k.

(e) Pour N = 60 et t = 25 s, faire afficher :


le temps en heures au bout duquel le rgime permanent est tabli ;
sur un mme graphique le profil de temprature en fonction de x tous,les 100
pas de temps.

Le rgime permanent est atteint au bout de 12.4444444444 heures.

PSI, Lyce Leconte de Lisle, Saint-Denis de la Runion. http://mathcpge.org/

You might also like