Lyc´ee Thiers - MPSI-3

publicité
Lycée Thiers
PYTHON - DEVOIR SURVEILLÉ 2
Exercice 1 - Algorithme probabiliste de recherche du k-ième plus petit élément d’une liste
On considère une liste L de longueur n ne comportant que des valeurs distinctes, prises dans l’ensemble [[1, N]] ( n ≤ N).
Soit k ∈ [[1, n]], on souhaite écrire une fonction qui renvoie le k-ième plus petit élément de cette liste.
Description de l’algorithme.
• On choisit une valeur dans la liste au hasard ;
• On partage alors la liste en 2 sous-listes, celle des éléments strictement inférieurs à l’élément choisi
et celle des éléments strictement supérieurs.
• Si la première liste comporte k − 1 éléments, on a de la chance, on renvoie l’élément choisi car c’est
le bon.
Si la première liste comporte k éléments ou plus, on remplace notre liste départ par cette liste et on
retourne au premier point.
Si la première liste comporte k − 2 éléments ou moins, notons ` sa longueur, on remplace notre liste
par la deuxième liste, k par k − 1 − ` et on retourne au premier point.
• On s’arrête lorsque la liste a une longueur k − 1 et on renvoie le dernier élément tiré au hasard.
[Qu. 1]
1) Écrire une fonction listeValeursDistinctes(n,N) qui retourne une liste de n valeurs distinctes
choisies dans l’intervalle [[1, N]].
On pourra, pour cela, s’inspirer d’un algorithme que l’on a déjà utilisé à plusieurs reprises et
qui réalise n permutations d’éléments de la liste L=[1,2,...,N].
Un exemple :
>>> liste2ValeursDistinctes (10 ,100)
[13, 77, 94, 22, 12, 64, 82, 42, 58, 53]
2) Soit x ∈ [[1, N]] et L une liste renvoyée par la fonction précédente. Définir une fonction partageInfSup(L,x)
qui renvoie un couple de listes infL,supL où infL est la liste des valeurs strictement inférieures
à x présentes dans la liste L et supL, la liste de celles qui sont strictement supérieures à x.
Voici un exemple :
>>> L= liste2ValeursDistinctes (10 ,100)
>>> L
[1, 38, 4, 86, 58, 55, 47, 95, 82, 90]
>>> partage (L ,58)
([1, 38, 4, 55, 47] , [86 , 95, 82, 90])
On remarquera dans cet exemple que, bien que x soit présent dans la liste, cette valeur ne se
retrouve pas dans les deux listes renvoyées.
PYTHON - DEVOIR SURVEILLÉ 2
2
3) Ecrire une fonction maj(k,L1,L2), qui étant données deux listes L1,L2 et un entier k, renvoie le
couple (L1,k) si la longueur de la liste L1 est inférieure ou égale k-1 et le couple (L2,k-1-len(L1))
sinon.
[Qu. 2] En utilisant les fonctions précédentes, définir une fonction kiemePlusPetit(L,k) qui renvoie,
lorsque la valeur de k est inférieure ou égale à la longueur de L, le k-ième plus petit élément de la liste
L.
[Qu. 3] L’exécution de listeValeursDistinctes(n,N) renvoie une liste L.
Cette liste peut-être considérée comme résultat de l’expérience aléatoire consistant à effectuer n tirages
avec remise dans une urne contenant N boules numérotées de 1 à N, en notant le numéro obtenu
après chaque tirage.
Pour k fixé, l’exécution de la fonction kiemePlusPetit(L,k) nécessite un certain temps ;). Ce temps,
étant une fonction de L, s’apparente à une variable aléatoire dont nous souhaitons estimer l’espérance.
Espérance qui elle, sera alors une fonction de n, N et k. On souhaite, N et k étant fixés, estimer cette
fonction de n pour mesurer l’efficacité de l’algoritme utilisé.
Pour cela on utilise le module time et dans ce module la fonction perf_counter().
Si dans un script on utilise l’instruction t0=perf_counter(), puis plus loin t1=perf_counter(), alors
t1-t0 est égale au temps exprimé en secondes qui s’est écoulé entre ces deux instructions.
1) Ecrire une fonction estimTempsMoyen(m,k,nombreExp) qui :
α) réalise, pour chaque entier i ∈ [[1, 10]], nombreExp exécutions de l’instruction
kiemePlusPetit(liste2ValeursDistinctes(i*m,100*m),k) ;
β) renvoie une liste de longueur 10 dont les valeurs sont les estimations des temps moyens
d’exécution de kiemePlusPetit(liste2ValeursDistinctes(i*m,100*m),k) pour i ∈ [[1, 10]]
obtenues à partir du α) .
2) Tester la fonction plot du module matplotlib.pyplot en saisissant dans le shell, après avoir
importé cette fonction, plot([1,3,5],[4,6,0]).
En utilisant la liste renvoyée par estimTempsMoyen(100,10,300), représenter graphiquement le
temps moyen estimé d’exécution de kiemePlusPetit(liste2ValeursDistinctes(i*100,10000),10)
pour i ∈ [[1, 10]] en fonction de i*100.
Quelle conjecture pouvez-vous faire sur la nature de cette fonction ?
Exercice 2 - POO pour la résolution d’équations polynomiales dans Q
On se propose de construire une classe pour manipuler des polynômes à coefficients entiers. Un
polynôme sera un objet ayant un unique attribut : la liste de ses coefficients. Par exemple, le polynôme
défini par :
P (x) = 3x4 − 7x3 − 4x2 + 14x − 4
sera représenté par un objet P tel que :
>>> P.coeffts
[-4, 14, -4, -7, 3]
On souhaite notamment mettre au point une méthode permettant de dresser la liste (éventuellement
vide) des racines rationnelles d’un polynôme à coefficients entiers.
On aura ainsi :
>>> P.racinesQ()
[(2, 1), (1, 3)]
PYTHON - DEVOIR SURVEILLÉ 2
3
Ce dernier résultat signifie que les racines rationnelles de P sont 2 et 1/3, ce qui est correct puisque,
pour tout x :
3x4 − 7x3 − 4x2 + 14x − 4 = (x − 2) (3x − 1) x2 − 2
h
i
[Qu. 1] Etant donné deux entiers u ∈ Z et n ∈ N, on souhaite calculer la liste 1, u, u2 , · · · , un .
1) Ecrire une fonction listePuissances(u, n) qui fasse cela, en une seule instruction Python. Combien de multiplications cette fonction effectue-t-elle ?
2) Ré-écrire cette fonction en faisant en sorte qu’elle effectue, en tout et pour tout, n multiplications
(ou n + 1 à la rigueur).
[Qu. 2] Définir la classe polyn et la méthode __init__ d’une manière appropriée (3 lignes de code) de
telle sorte que, pour définir le polynôme P du début de l’énoncé, on exécute la commande suivante :
>>> P = polyn([-4, 14, -4, -7, 3])
[Qu. 3] Evaluation “naïve” d’un polynôme.
En s’inspirant de Qu. 1-2), écrire une méthode eval telle que P.eval(a) renvoie P (a) . On rappelle la
forme de l’en-tête de définition :
def eval(self, a):
...
Combien de multiplications cette fonction effectue-t-elle ?
[Qu. 4] Il n’est pas nécessaire de traiter cette question pour aborder les deux suivantes.
Etant donnés un polynôme P (x) =
n
X
ck xk (avec n > 1 et c0 , · · · , cn entiers) et un entier a, on admet
k=0
qu’il existe des entiers q0 , · · · , qn−1 tels que :
P (x) = (x − a)
n−1
X
qk xk + P (a)
k=0
1) Pour tout k ∈ {0, · · · , n} , exprimer ck en fonction des qi et de a. On distinguera trois cas : k = n,
1 6 k 6 n − 1 et k = 0.
2) En déduire une méthode pour calculer P (a) qui requiert en tout n multiplications.
3) Ecrire une méthode evalBis, telle que P.evalBis(a) renvoie P (a) en appliquant cette méthode.
[Qu. 5] Pour savoir si un rationnel u/v (u, v entiers et v , 0) est racine d’un polynôme P (x) =
n
X
ck xk ,
k=0
on peut calculer une expression qui ne fasse intervenir que des entiers et dont la valeur soit aussi un
entier.
1) Préciser cela.
2) En déduire une méthode admetLaRacine telle que P.admetLaRacine(u, v) renvoie True si P
0 et False sinon. On pourra utiliser la fonction listeDesPuissances (cf. Qu. 1).
u
v
=
PYTHON - DEVOIR SURVEILLÉ 2
4
[Qu. 6] On rappelle le principe du test des racines rationnelles pour la résolution d’une équation
algébrique :
Etant donnés n ∈ N? et a0 , · · · , an ∈ Z, avec an , 0 et a0 , 0, on s’intéresse à l’équation
an xn + · · · + a1 x + a0 = 0
(1)
p
On peut montrer à l’aide du théorème de Gauss 1, que si (1) possède une solution rationnelle (mise
q
sous forme irréductible, c’est-à-dire avec p, q ∈ Z × N? et p ∧ q = 1), alors :
p | a0
et q | an
1) Ecrire une fonction divPos qui renvoie la liste des diviseurs positifs d’un entier. En déduire une
fonction diviseurs qui renvoie la liste de tous les diviseurs (positifs et négatifs) d’un entier. On
aura ainsi :
>>>
[1,
>>>
[1,
divPos(12)
2, 3, 4, 6, 12]
diviseurs(12)
2, 3, 4, 6, 12, -1, -2, -3, -4, -6, -12]
2) Ecrire une fonction
qui, étant données deux listes N et D d’entiers non nuls, renvoie la
mixList
liste des couples ni , d j où ni est un terme de N et d j un terme de D.
3) Programmer le test des racines rationnelles sous la forme d’une méthode racinesQ. Cette méthode, appliquée à un polynôme P, devra renvoyer une liste de couples (u, v) d’entiers (v , 0) de
telle sorte que les fractions u/v soient les racines rationnelles de P. Attention : dans cette liste,
plusieurs couples pourront représenter un même rationnel.
4) Quelles sont les solutions rationnelles de l’équation suivante ?
77x6 + 240x5 + 128x4 + 28x3 − 120x2 − 8x + 15 = 0
5) Même question pour l’équation :
377x69 − 191x68 + 24x67 − 754x2 + 382x − 48 = 0
6) Ecrire une version plus aboutie de la méthode racinesQ, en essayant de corriger le défaut mentionné au 3). En outre, au lieu de renvoyer une liste, on affichera les racines rationnelles sous la
forme u/v, à raison d’une racine par ligne.
1. Si a, b, c ∈ N? sont tels que a | bc et PGCD (a, b) = 1, alors a | c.
Téléchargement