SlideShare une entreprise Scribd logo
Informatique tronc commun, MP, premier devoir surveillé
Durée deux heures.
1 Bases de données (Mines 2017)
On modélise ici un réseau routier par un ensemble de croisements et de voies reliant ces croisements. Les
voies partent d’un croisement et arrivent à un autre croisement. Ainsi, pour modéliser une route à double
sens, on utilise deux voies circulant en sens opposés. La base de données du réseau routier est constituée des
relations suivantes :
• Croisement(id, longitude, latitude)
• Voie(id, longueur, id_croisement_debut, id_croisement_fin)
Remarque : Cela signifie que la base est constituées de deux tables : Croisement et Voie ; que les colonnes de
Croisement sont id, longitude, et latitude ; que les colonnes de Voie sont id, longueur, id_croisement_debut,
et id_croisement_fin ; et les colonnes soulignées sont les clés primaires de leur tables.
Dans la suite on considère c l’identifiant (id) d’un croisement donné.
1. (1 pt(s)) Écrire la requête SQL qui renvoie les identifiants des croisements atteignables en utilisant
une seule voie à partir du croisement ayant l’identifiant c.
SELECT id_croisement_fin
FROM Voies
WHERE id_croisement_debut = c
;
2. (2 pt(s)) Écrire la requête SQL qui renvoie les longitudes et latitudes des croisements atteignables en
utilisant une seule voie, à partir du croisement c.
SELECT Croisement.longitude, Croisement.latitude
FROM Croisement JOIN Voie ON Voie.id_croisement_fin=Croisement.id
WHERE Voie.id_croisement_debut = c
;
3. (1 pt(s)) Que renvoie la requête SQL suivante ?
SELECT V2 . id_croisement_fin
FROM Voie AS V1 JOIN Voie AS V2
ON V1 . id_croisement_fin = V2 . id_croisement_debut
WHERE V1 . id_croisement_debut = c
Cette requête renvoie les identifiants des croisements atteignables en deux voies. L’alias V1 représente la première
voie empruntée, et V2 la seconde.
4. (1 pt(s)) Préciser l’importance du AS V1 et du AS V2.
On joint ici la table Voie avec elle-même. Il est nécessaire de donner un alias à chaque copie de la table sans
quoi sql ne saura pas dans laquelle chercher les champs demandés.
5. On considère l’identifiant d d’un nouveau croisement. Écrire une requête qui renvoie tous les itinéraires
formés de deux voies permettant d’aller de c vers d, et pour chacun la longueur totale du trajet.
SELECT V1 . id_croisement_debut , V1 . id_croisement_fin , V2 . id_croisement_fin ,
V1 . longueur+V2 . longueur AS longueurDuParcours
FROM Voie as V1 JOIN Voie as V2
ON V1 . id_croisement_fin = V2 . id_croisement_debut
WHERE V1 . id_croisement_debut = c AND V2 . id_croisement_fin = d
;
1
2 Piles : algorithme de Horner
Un polynôme sera représenté par la liste de ses coefficients, par exemple [1,5,2,3] représente le polynôme
1 + 5X + 2X2
+ 3X3
. Le but est décrire une fonction d’évaluation, qui prendra en entrée un polynôme P et
un nombre x et qui calculera P(x).
Dans la suite, nous notons x un flottant, P un polynôme, n son degré, et a0, . . . , an ses coefficients.
1. (1 pt(s)) Quel est le nombre de multiplications utilisé pour calculer P(x) par l’algorithme naïf où pour
tout k ∈ N, xk
est calculé par k multiplications ?
Pour tout k ∈ J0, nK, xk
est calculé en k multiplications, donc akxk
en k + 1 multiplications, et le nombre total
de multiplications est :
n
X
k=0
k + 1 =
(n + 1)(n + 2)
2
= Θn→∞

n2

.
Ainsi la complexité est quadratique.
2. À l’aide par exemple d’une comparaison séries-intégrales, montrer que
n
X
k=1
ln(k) ∼
n→∞
n ln(n).
Soit n ∈ N∗
.
Pour tout k ∈ J1, nK et tout t ∈ [k, k + 1], ln(k) 6 ln(t) ln(k + 1), d’où, puisque la fonction ln est croissante :
ln(k) 6
Z k+1
t=k
ln(t) 6 ln(k + 1).
Notons F : x 7→ x ln(x) − x, c’est une primitive de ln, et donc :
ln(k) 6 F(k + 1) − F(k) 6 ln(k + 1).
On déduit l’encadrement de ln(k) :
Pour tout k ∈ J2, nK :
F(k) − F(k − 1) 6 ln(k) 6 F(k + 1) − F(k)
Puis en sommant :
F(n) − F(1) 6
n
X
k=2
ln(k) 6 F(n + 1) − F(2)
Comme ln(1) = 0,
Pn
k=2
ln(k) =
Pn
k=1
ln(k)
Nous voulons prouver que limn→∞
Pn
k=1
ln(k)
n ln(n)
= 1, encadrons ce quotient :
Pour tout n ∈ N∗
:
n ln(n) − n + 1
n ln(n)
6
Pn
k=1
ln(k)
n ln(n)
6
(n + 1) ln(n + 1) − (n + 1) − F(2)
n ln(n)
Ainsi le quotient est encadré par deux suites qui convergent vers 1, il converge donc lui aussi vers 1.
D’où limn→∞
Pn
k=1
ln(k)
n ln(n)
= 1, puis
Pn
k=1
ln(k) ∼
n→∞
n ln(n).
3. Donner l’ordre de grandeur du nombre de multiplications si on calcule les puissances par l’algorithme
d’exponentiation rapide vu en cours.
Pour tout k ∈ J1, nK, le calcul de xk
se fera en O(log2(k)) multiplications. Donc le nombre de multiplication
nécessaire au calcul de P(x) sera :
n
X
k=1
1 + O(log2(k)) = n +
n
X
k=1
O(log2(k)) = n + O


n
X
k=1
log2(k)

 = n +
O(n log n) = O(n log n).
4. Un élève propose cette fonction :
2
def evalue (P, x ) :
xpi=1
r e s=0
for i in range (0 , len (P) ) :
# i c i , xpi contient . . . . et res contient . . .
xpi∗=x
r e s+=P[ i ] ∗ xpi
return r e s
(a) (0,5 pt(s)) ] Combien de multiplications sont effectuées pour évaluer un polynôme de degré n ?
Il y a deux multiplications à chaque tour de boucle, donc un total de 2n multiplications.
(b) (0,5 pt(s)) À quoi sert la variable xpi ?
La variable xpi enregistre xi
pour pouvoir calculer xi+1
plus rapidement au tour de boucle prochain.
(c) (1,5 pt(s)) Il a une erreur dans ce code. La corriger, et compléter le commentaire dans la boucle.
Avec le code de l’élève, xpi contient xi+1
au moment où il est multiplié par P[i]. On calcule donc
n
X
k=0
akxk+1
. Voici une version corrigée avec l’invariant de boucle complété :
def evalue (P, x ) :
xpi=1
r e s=0
for i in range (0 , len (P) ) :
# i c i , xpi contient x∗∗ i et res contient l a somme pour k de 0 à i −1 de ak∗x∗∗k
r e s+=P[ i ] ∗ xpi
xpi∗=x
return r e s
(d) (2 pt(s)) Prouver que la fonction est correcte en utilisant la propriété en commentaire comme
invariant de boucle.
Pour tout i ∈ J0, n + 1K, notons P(i) : « au début de l’itération i (c’est-à-dire à la fin de l’itération i − 1),
xpi contient xi
et res contient
i−1
X
k=0
akxk
. »
• initialisation : au début de l’itération 0, c’est-à-dire avant de rentrer dans la boucle, xpi contient 1,
qui est bien égal à x0
, et res contient 0, qui est bien égal à
−1
X
k=0
akxk
.
• hérédité : Soit i ∈ J0, nK, supposons P(i). On aborde l’itération i + 1 de la boucle. Au début, par
P(i), xpi contient xi
et res contient
i−1
X
k=0
akxk
.
On effectue res+=P[i]*xpi, res contient alors :
i−1
X
k=0
akxk
+ ai ∗ xi
, qui vaut bien
i
X
k=0
akxk
.
Ensuite, on effectue xpi*=x, à la suite de quoi xpi contient xi
∗ i c’est-à-dire xi+1
.
Ainsi, au début de l’itération i + 1, xpi contiendra xi+1
et res contiendra
i
X
k=0
akxk
. Donc P(i + 1).
Ainsi, P est invariant de boucle : ∀i ∈ J0, n + 1K, P(i). En particulier, d’après P(n + 1), à la fin de
l’itération n, c’est-à-dire à la sortie de la boucle, res contient
n
X
k=0
akxk
, qui est le résultat renvoyé et le
résultat attendu.
5. On propose enfin l’algorithme de Horner, basé sur la remarque suivante :
P(x) = a0 +

a1 + a2x + . . . anxn−1

× x.
Pour cet algorithme, il sera plus pratique de ranger les coefficients dans une pile, le coefficient constant
étant au sommet et le coefficient de plus haut degré au fond. Ainsi, P sera représenté par [an,...,a1,a0]
et le polynôme a1 + a2X + . . . anXn−1
n’est autre que celui représenté par la pile [an,...,a1].
3
(a) Programmer l’algorithme de Horner.
Une version récursive permet de traduire immédiatement la formule proposée par l’énoncé :
def horner (P, x ) :
i f P= [ ] : return 0
else :
return P. pop ( ) + x∗ horner (P, x )
(b) Combien de multiplications sont effectuées pour calculer P(x) ?
Il y a une multiplication dans chaque appel récursif, et n appels, donc n multiplications.
3 Récursivité : résolution d’un sudoku
Nous allons étudier ici une méthode appelée backtracking qui permet de résoudre un sudoku et de
nombreux problèmes similaires.
Le principe est extrêmement basique : on choisit la case où il y a le moins chiffres possibles pour respecter
les règles du jeu, on en inscrit un, et on poursuit la résolution. Si on se rend compte que la résolution est
impossible, on efface alors le chiffre qu’on avait inscrit (c’est cette étape qui se nomme backtracking, pour
retour en arrière).
Rappel des règles et implémentation : Nous considérons une grille de format 9 × 9, qui sera repré-
sentée par un objet de type list list sous Python. Certaines cases sont déjà remplie par un chiffre de
J1, 9K. En Python, nous mettrons 0 dans les cases non remplies.
Par exemple, voici une grille complètement vide :
[[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]]
Le but est d’inscrire un chiffre de J1, 9K dans chaque case de la grille, en vérifiant les trois règles suivantes :
(i) Pour tout i ∈ J0, 8K, les chiffres inscrit sur la ligne i sont deux à deux distincts ;
(ii) Pour tout j ∈ J0, 8K, les chiffres inscrit sur la colonne j sont deux à deux distincts ;
(iii) La grille étant partagées en 9 blocs carrés de format 3 × 3, les chiffres inscrits dans chaque bloc sont
deux à deux distincts.
1. Dans un premier temps, on se concentre sur la fonction principale, qui contient le squelette de l’algo-
rithme. On supposera déjà connues les fonctions utilitaires suivantes :
• chiffresPossible telle que pour toute grille g et tout (i, j) ∈ J0, 9J2
, chiffresPossible(g,i,j)
renvoie la liste des chiffres possibles en case (i, j) de la grille g pour vérifier les trois conditions de
la règle du jeu.
• prochaineCaseARemplir telle que pour toute grille g, prochaineCaseARemplir(g) renvoie :
 None si toutes les cases sont déjà remplies (auquel cas la grille est résolue !)
 un triplet (i, j, listePoss) où (i, j) est une case ayant un minimum de possibilités et listePoss
est la liste de ces possibilités dans le cas contraire.
4
Écrire alors le programme resolution prenant en entrée une grille g et renvoyant True si cette
grille est remplissable et False sinon. En outre, ce programme remplira g au fur et à mesure, de
sorte que si il renvoie True, g soit alors complètement remplie. Par contre, si il renvoie False, la
grille devra être revenue à son état initial.
On propose la stratégie suivante :
 Utiliser le programme prochaineCaseARemplir pour repérer si la grille est déjà remplie, et
dans le cas contraire, identifier la prochaine case à aller remplir ainsi que la liste listePoss des
possibilités pour remplir cette case.
 Pour tout n ∈ listePoss, mettre n dans la case, et reappeler récursivement la fonction
resolution. Si cette fonction renvoie True c’est gagné ! Si cette fonction renvoie False c’est
qu’il n’a pas été possible de compléter la grille en y mettant n : dans ce cas, effacer n.
 Si toutes les valeurs de listePoss ont été testées sans succès, c’est qu’il n’est pas possible de
remplir la grille.
Voir le fichier .py
2. bonus : Écrire les fonctions chiffresPossibles et prochaineCaseARemplir pour obtenir un solveur
de sudoku complet.
5

Contenu connexe

Tendances

Algorithme & structures de données Chap I
Algorithme & structures de données Chap IAlgorithme & structures de données Chap I
Algorithme & structures de données Chap I
Ines Ouaz
 
Examen principal - Algorithme & Structures de données
Examen principal - Algorithme & Structures de donnéesExamen principal - Algorithme & Structures de données
Examen principal - Algorithme & Structures de données
Ines Ouaz
 
algorithme tronc commun lycée
algorithme tronc commun lycéealgorithme tronc commun lycée
algorithme tronc commun lycée
Kayl Mido
 
resume algo 2023.pdf
resume algo 2023.pdfresume algo 2023.pdf
resume algo 2023.pdf
salah fenni
 
Exercices algo
Exercices algoExercices algo
Exercices algo
NAWEL_DERBEL
 
01 correction-td smia-s2-info2
01 correction-td smia-s2-info201 correction-td smia-s2-info2
01 correction-td smia-s2-info2
L’Université Hassan 1er Settat
 
exercices-corriges-dalgorithmique
exercices-corriges-dalgorithmiqueexercices-corriges-dalgorithmique
exercices-corriges-dalgorithmique
fast xp
 
algorithmique
algorithmiquealgorithmique
algorithmique
ABID Mehdi
 
Les algorithmes recurrents
Les algorithmes recurrentsLes algorithmes recurrents
Les algorithmes recurrents
mohamed_SAYARI
 
Corrige exercices pascal_fenni_2018
Corrige exercices pascal_fenni_2018Corrige exercices pascal_fenni_2018
Corrige exercices pascal_fenni_2018
salah fenni
 
Exercices_Python_Fenni_2023 -corrigé.pdf
Exercices_Python_Fenni_2023 -corrigé.pdfExercices_Python_Fenni_2023 -corrigé.pdf
Exercices_Python_Fenni_2023 -corrigé.pdf
salah fenni
 
Algorithmique programmation2018
Algorithmique programmation2018Algorithmique programmation2018
Algorithmique programmation2018
salah fenni
 
FormationPython2019.pptx
FormationPython2019.pptxFormationPython2019.pptx
FormationPython2019.pptx
LamissGhoul1
 
Examen principal - Fondement Multimedia - correction
Examen principal - Fondement Multimedia - correctionExamen principal - Fondement Multimedia - correction
Examen principal - Fondement Multimedia - correction
Ines Ouaz
 
Corrigés exercices langage C
Corrigés exercices langage CCorrigés exercices langage C
Corrigés exercices langage C
coursuniv
 
Exercices sur-python-turtle-corrige
Exercices sur-python-turtle-corrigeExercices sur-python-turtle-corrige
Exercices sur-python-turtle-corrige
WajihBaghdadi1
 
Algorithmique
AlgorithmiqueAlgorithmique
Algorithmique
elharraj
 

Tendances (20)

Algorithme & structures de données Chap I
Algorithme & structures de données Chap IAlgorithme & structures de données Chap I
Algorithme & structures de données Chap I
 
Examen principal - Algorithme & Structures de données
Examen principal - Algorithme & Structures de donnéesExamen principal - Algorithme & Structures de données
Examen principal - Algorithme & Structures de données
 
algorithme tronc commun lycée
algorithme tronc commun lycéealgorithme tronc commun lycée
algorithme tronc commun lycée
 
Recursiviteeeeeeeeee
RecursiviteeeeeeeeeeRecursiviteeeeeeeeee
Recursiviteeeeeeeeee
 
resume algo 2023.pdf
resume algo 2023.pdfresume algo 2023.pdf
resume algo 2023.pdf
 
Exercices algo
Exercices algoExercices algo
Exercices algo
 
01 correction-td smia-s2-info2
01 correction-td smia-s2-info201 correction-td smia-s2-info2
01 correction-td smia-s2-info2
 
exercices-corriges-dalgorithmique
exercices-corriges-dalgorithmiqueexercices-corriges-dalgorithmique
exercices-corriges-dalgorithmique
 
Exo algo
Exo algoExo algo
Exo algo
 
algorithmique
algorithmiquealgorithmique
algorithmique
 
Les algorithmes recurrents
Les algorithmes recurrentsLes algorithmes recurrents
Les algorithmes recurrents
 
Corrige exercices pascal_fenni_2018
Corrige exercices pascal_fenni_2018Corrige exercices pascal_fenni_2018
Corrige exercices pascal_fenni_2018
 
Serie2
Serie2Serie2
Serie2
 
Exercices_Python_Fenni_2023 -corrigé.pdf
Exercices_Python_Fenni_2023 -corrigé.pdfExercices_Python_Fenni_2023 -corrigé.pdf
Exercices_Python_Fenni_2023 -corrigé.pdf
 
Algorithmique programmation2018
Algorithmique programmation2018Algorithmique programmation2018
Algorithmique programmation2018
 
FormationPython2019.pptx
FormationPython2019.pptxFormationPython2019.pptx
FormationPython2019.pptx
 
Examen principal - Fondement Multimedia - correction
Examen principal - Fondement Multimedia - correctionExamen principal - Fondement Multimedia - correction
Examen principal - Fondement Multimedia - correction
 
Corrigés exercices langage C
Corrigés exercices langage CCorrigés exercices langage C
Corrigés exercices langage C
 
Exercices sur-python-turtle-corrige
Exercices sur-python-turtle-corrigeExercices sur-python-turtle-corrige
Exercices sur-python-turtle-corrige
 
Algorithmique
AlgorithmiqueAlgorithmique
Algorithmique
 

Similaire à Video

Chapitre 3 NP-complétude
Chapitre 3 NP-complétudeChapitre 3 NP-complétude
Chapitre 3 NP-complétude
Sana Aroussi
 
transparents-Algo-complexite.pdf
transparents-Algo-complexite.pdftransparents-Algo-complexite.pdf
transparents-Algo-complexite.pdf
abdallahyoubiidrissi1
 
Cours programmation en matlab2 (1)
Cours programmation en matlab2 (1)Cours programmation en matlab2 (1)
Cours programmation en matlab2 (1)
Guesmi Amal
 
Sommation séries entières
Sommation séries entièresSommation séries entières
Sommation séries entières
Loïc Dilly
 
Cours series fourier
Cours series fourierCours series fourier
Cours series fourier
ismailkziadi
 
Cours series fourier
Cours series fourierCours series fourier
Cours series fourier
Mehdi Maroun
 
Chapitre 2 complexité
Chapitre 2 complexitéChapitre 2 complexité
Chapitre 2 complexité
Sana Aroussi
 
CAPES maths 2019 composition 2
CAPES maths 2019 composition 2CAPES maths 2019 composition 2
CAPES maths 2019 composition 2
Dany-Jack Mercier
 
Mathématiques et Python
Mathématiques et PythonMathématiques et Python
Mathématiques et Python
Dany-Jack Mercier
 
124776153 td-automatique-1 a-jmd-2011
124776153 td-automatique-1 a-jmd-2011124776153 td-automatique-1 a-jmd-2011
124776153 td-automatique-1 a-jmd-2011
sunprass
 
Matlab Travaux Pratique
Matlab Travaux Pratique Matlab Travaux Pratique
Matlab Travaux Pratique
Smee Kaem Chann
 
Traitement des données massives (INF442, A4)
Traitement des données massives (INF442, A4)Traitement des données massives (INF442, A4)
Traitement des données massives (INF442, A4)
Frank Nielsen
 
Chapitre 2 -Complexité des problèmes avec correction.pdf
Chapitre 2 -Complexité des problèmes avec correction.pdfChapitre 2 -Complexité des problèmes avec correction.pdf
Chapitre 2 -Complexité des problèmes avec correction.pdf
MbarkiIsraa
 
CAPES maths 2019 composition 1 (option informatique)
CAPES maths 2019 composition 1 (option informatique)CAPES maths 2019 composition 1 (option informatique)
CAPES maths 2019 composition 1 (option informatique)
Dany-Jack Mercier
 
Chapitre 2 plus court chemin
Chapitre 2 plus court cheminChapitre 2 plus court chemin
Chapitre 2 plus court chemin
Sana Aroussi
 
Epreuve de mathématiques informatique (modélisation) Agro/Véto BCPST 2017
Epreuve de mathématiques informatique (modélisation) Agro/Véto BCPST 2017Epreuve de mathématiques informatique (modélisation) Agro/Véto BCPST 2017
Epreuve de mathématiques informatique (modélisation) Agro/Véto BCPST 2017
Ahmed Ammar Rebai PhD
 
Introduction à Python - Achraf Kacimi El Hassani
Introduction à Python - Achraf Kacimi El HassaniIntroduction à Python - Achraf Kacimi El Hassani
Introduction à Python - Achraf Kacimi El Hassani
Shellmates
 

Similaire à Video (20)

Chapitre 3 NP-complétude
Chapitre 3 NP-complétudeChapitre 3 NP-complétude
Chapitre 3 NP-complétude
 
transparents-Algo-complexite.pdf
transparents-Algo-complexite.pdftransparents-Algo-complexite.pdf
transparents-Algo-complexite.pdf
 
246242769 sequence-1-pdf
246242769 sequence-1-pdf246242769 sequence-1-pdf
246242769 sequence-1-pdf
 
Cours programmation en matlab2 (1)
Cours programmation en matlab2 (1)Cours programmation en matlab2 (1)
Cours programmation en matlab2 (1)
 
Sommation séries entières
Sommation séries entièresSommation séries entières
Sommation séries entières
 
Cours series fourier
Cours series fourierCours series fourier
Cours series fourier
 
Cours series fourier
Cours series fourierCours series fourier
Cours series fourier
 
Chapitre 2 complexité
Chapitre 2 complexitéChapitre 2 complexité
Chapitre 2 complexité
 
Exercice intégrales
Exercice intégralesExercice intégrales
Exercice intégrales
 
Récursivité
RécursivitéRécursivité
Récursivité
 
CAPES maths 2019 composition 2
CAPES maths 2019 composition 2CAPES maths 2019 composition 2
CAPES maths 2019 composition 2
 
Mathématiques et Python
Mathématiques et PythonMathématiques et Python
Mathématiques et Python
 
124776153 td-automatique-1 a-jmd-2011
124776153 td-automatique-1 a-jmd-2011124776153 td-automatique-1 a-jmd-2011
124776153 td-automatique-1 a-jmd-2011
 
Matlab Travaux Pratique
Matlab Travaux Pratique Matlab Travaux Pratique
Matlab Travaux Pratique
 
Traitement des données massives (INF442, A4)
Traitement des données massives (INF442, A4)Traitement des données massives (INF442, A4)
Traitement des données massives (INF442, A4)
 
Chapitre 2 -Complexité des problèmes avec correction.pdf
Chapitre 2 -Complexité des problèmes avec correction.pdfChapitre 2 -Complexité des problèmes avec correction.pdf
Chapitre 2 -Complexité des problèmes avec correction.pdf
 
CAPES maths 2019 composition 1 (option informatique)
CAPES maths 2019 composition 1 (option informatique)CAPES maths 2019 composition 1 (option informatique)
CAPES maths 2019 composition 1 (option informatique)
 
Chapitre 2 plus court chemin
Chapitre 2 plus court cheminChapitre 2 plus court chemin
Chapitre 2 plus court chemin
 
Epreuve de mathématiques informatique (modélisation) Agro/Véto BCPST 2017
Epreuve de mathématiques informatique (modélisation) Agro/Véto BCPST 2017Epreuve de mathématiques informatique (modélisation) Agro/Véto BCPST 2017
Epreuve de mathématiques informatique (modélisation) Agro/Véto BCPST 2017
 
Introduction à Python - Achraf Kacimi El Hassani
Introduction à Python - Achraf Kacimi El HassaniIntroduction à Python - Achraf Kacimi El Hassani
Introduction à Python - Achraf Kacimi El Hassani
 

Video

  • 1. Informatique tronc commun, MP, premier devoir surveillé Durée deux heures. 1 Bases de données (Mines 2017) On modélise ici un réseau routier par un ensemble de croisements et de voies reliant ces croisements. Les voies partent d’un croisement et arrivent à un autre croisement. Ainsi, pour modéliser une route à double sens, on utilise deux voies circulant en sens opposés. La base de données du réseau routier est constituée des relations suivantes : • Croisement(id, longitude, latitude) • Voie(id, longueur, id_croisement_debut, id_croisement_fin) Remarque : Cela signifie que la base est constituées de deux tables : Croisement et Voie ; que les colonnes de Croisement sont id, longitude, et latitude ; que les colonnes de Voie sont id, longueur, id_croisement_debut, et id_croisement_fin ; et les colonnes soulignées sont les clés primaires de leur tables. Dans la suite on considère c l’identifiant (id) d’un croisement donné. 1. (1 pt(s)) Écrire la requête SQL qui renvoie les identifiants des croisements atteignables en utilisant une seule voie à partir du croisement ayant l’identifiant c. SELECT id_croisement_fin FROM Voies WHERE id_croisement_debut = c ; 2. (2 pt(s)) Écrire la requête SQL qui renvoie les longitudes et latitudes des croisements atteignables en utilisant une seule voie, à partir du croisement c. SELECT Croisement.longitude, Croisement.latitude FROM Croisement JOIN Voie ON Voie.id_croisement_fin=Croisement.id WHERE Voie.id_croisement_debut = c ; 3. (1 pt(s)) Que renvoie la requête SQL suivante ? SELECT V2 . id_croisement_fin FROM Voie AS V1 JOIN Voie AS V2 ON V1 . id_croisement_fin = V2 . id_croisement_debut WHERE V1 . id_croisement_debut = c Cette requête renvoie les identifiants des croisements atteignables en deux voies. L’alias V1 représente la première voie empruntée, et V2 la seconde. 4. (1 pt(s)) Préciser l’importance du AS V1 et du AS V2. On joint ici la table Voie avec elle-même. Il est nécessaire de donner un alias à chaque copie de la table sans quoi sql ne saura pas dans laquelle chercher les champs demandés. 5. On considère l’identifiant d d’un nouveau croisement. Écrire une requête qui renvoie tous les itinéraires formés de deux voies permettant d’aller de c vers d, et pour chacun la longueur totale du trajet. SELECT V1 . id_croisement_debut , V1 . id_croisement_fin , V2 . id_croisement_fin , V1 . longueur+V2 . longueur AS longueurDuParcours FROM Voie as V1 JOIN Voie as V2 ON V1 . id_croisement_fin = V2 . id_croisement_debut WHERE V1 . id_croisement_debut = c AND V2 . id_croisement_fin = d ; 1
  • 2. 2 Piles : algorithme de Horner Un polynôme sera représenté par la liste de ses coefficients, par exemple [1,5,2,3] représente le polynôme 1 + 5X + 2X2 + 3X3 . Le but est décrire une fonction d’évaluation, qui prendra en entrée un polynôme P et un nombre x et qui calculera P(x). Dans la suite, nous notons x un flottant, P un polynôme, n son degré, et a0, . . . , an ses coefficients. 1. (1 pt(s)) Quel est le nombre de multiplications utilisé pour calculer P(x) par l’algorithme naïf où pour tout k ∈ N, xk est calculé par k multiplications ? Pour tout k ∈ J0, nK, xk est calculé en k multiplications, donc akxk en k + 1 multiplications, et le nombre total de multiplications est : n X k=0 k + 1 = (n + 1)(n + 2) 2 = Θn→∞ n2 . Ainsi la complexité est quadratique. 2. À l’aide par exemple d’une comparaison séries-intégrales, montrer que n X k=1 ln(k) ∼ n→∞ n ln(n). Soit n ∈ N∗ . Pour tout k ∈ J1, nK et tout t ∈ [k, k + 1], ln(k) 6 ln(t) ln(k + 1), d’où, puisque la fonction ln est croissante : ln(k) 6 Z k+1 t=k ln(t) 6 ln(k + 1). Notons F : x 7→ x ln(x) − x, c’est une primitive de ln, et donc : ln(k) 6 F(k + 1) − F(k) 6 ln(k + 1). On déduit l’encadrement de ln(k) : Pour tout k ∈ J2, nK : F(k) − F(k − 1) 6 ln(k) 6 F(k + 1) − F(k) Puis en sommant : F(n) − F(1) 6 n X k=2 ln(k) 6 F(n + 1) − F(2) Comme ln(1) = 0, Pn k=2 ln(k) = Pn k=1 ln(k) Nous voulons prouver que limn→∞ Pn k=1 ln(k) n ln(n) = 1, encadrons ce quotient : Pour tout n ∈ N∗ : n ln(n) − n + 1 n ln(n) 6 Pn k=1 ln(k) n ln(n) 6 (n + 1) ln(n + 1) − (n + 1) − F(2) n ln(n) Ainsi le quotient est encadré par deux suites qui convergent vers 1, il converge donc lui aussi vers 1. D’où limn→∞ Pn k=1 ln(k) n ln(n) = 1, puis Pn k=1 ln(k) ∼ n→∞ n ln(n). 3. Donner l’ordre de grandeur du nombre de multiplications si on calcule les puissances par l’algorithme d’exponentiation rapide vu en cours. Pour tout k ∈ J1, nK, le calcul de xk se fera en O(log2(k)) multiplications. Donc le nombre de multiplication nécessaire au calcul de P(x) sera : n X k=1 1 + O(log2(k)) = n + n X k=1 O(log2(k)) = n + O   n X k=1 log2(k)   = n + O(n log n) = O(n log n). 4. Un élève propose cette fonction : 2
  • 3. def evalue (P, x ) : xpi=1 r e s=0 for i in range (0 , len (P) ) : # i c i , xpi contient . . . . et res contient . . . xpi∗=x r e s+=P[ i ] ∗ xpi return r e s (a) (0,5 pt(s)) ] Combien de multiplications sont effectuées pour évaluer un polynôme de degré n ? Il y a deux multiplications à chaque tour de boucle, donc un total de 2n multiplications. (b) (0,5 pt(s)) À quoi sert la variable xpi ? La variable xpi enregistre xi pour pouvoir calculer xi+1 plus rapidement au tour de boucle prochain. (c) (1,5 pt(s)) Il a une erreur dans ce code. La corriger, et compléter le commentaire dans la boucle. Avec le code de l’élève, xpi contient xi+1 au moment où il est multiplié par P[i]. On calcule donc n X k=0 akxk+1 . Voici une version corrigée avec l’invariant de boucle complété : def evalue (P, x ) : xpi=1 r e s=0 for i in range (0 , len (P) ) : # i c i , xpi contient x∗∗ i et res contient l a somme pour k de 0 à i −1 de ak∗x∗∗k r e s+=P[ i ] ∗ xpi xpi∗=x return r e s (d) (2 pt(s)) Prouver que la fonction est correcte en utilisant la propriété en commentaire comme invariant de boucle. Pour tout i ∈ J0, n + 1K, notons P(i) : « au début de l’itération i (c’est-à-dire à la fin de l’itération i − 1), xpi contient xi et res contient i−1 X k=0 akxk . » • initialisation : au début de l’itération 0, c’est-à-dire avant de rentrer dans la boucle, xpi contient 1, qui est bien égal à x0 , et res contient 0, qui est bien égal à −1 X k=0 akxk . • hérédité : Soit i ∈ J0, nK, supposons P(i). On aborde l’itération i + 1 de la boucle. Au début, par P(i), xpi contient xi et res contient i−1 X k=0 akxk . On effectue res+=P[i]*xpi, res contient alors : i−1 X k=0 akxk + ai ∗ xi , qui vaut bien i X k=0 akxk . Ensuite, on effectue xpi*=x, à la suite de quoi xpi contient xi ∗ i c’est-à-dire xi+1 . Ainsi, au début de l’itération i + 1, xpi contiendra xi+1 et res contiendra i X k=0 akxk . Donc P(i + 1). Ainsi, P est invariant de boucle : ∀i ∈ J0, n + 1K, P(i). En particulier, d’après P(n + 1), à la fin de l’itération n, c’est-à-dire à la sortie de la boucle, res contient n X k=0 akxk , qui est le résultat renvoyé et le résultat attendu. 5. On propose enfin l’algorithme de Horner, basé sur la remarque suivante : P(x) = a0 + a1 + a2x + . . . anxn−1 × x. Pour cet algorithme, il sera plus pratique de ranger les coefficients dans une pile, le coefficient constant étant au sommet et le coefficient de plus haut degré au fond. Ainsi, P sera représenté par [an,...,a1,a0] et le polynôme a1 + a2X + . . . anXn−1 n’est autre que celui représenté par la pile [an,...,a1]. 3
  • 4. (a) Programmer l’algorithme de Horner. Une version récursive permet de traduire immédiatement la formule proposée par l’énoncé : def horner (P, x ) : i f P= [ ] : return 0 else : return P. pop ( ) + x∗ horner (P, x ) (b) Combien de multiplications sont effectuées pour calculer P(x) ? Il y a une multiplication dans chaque appel récursif, et n appels, donc n multiplications. 3 Récursivité : résolution d’un sudoku Nous allons étudier ici une méthode appelée backtracking qui permet de résoudre un sudoku et de nombreux problèmes similaires. Le principe est extrêmement basique : on choisit la case où il y a le moins chiffres possibles pour respecter les règles du jeu, on en inscrit un, et on poursuit la résolution. Si on se rend compte que la résolution est impossible, on efface alors le chiffre qu’on avait inscrit (c’est cette étape qui se nomme backtracking, pour retour en arrière). Rappel des règles et implémentation : Nous considérons une grille de format 9 × 9, qui sera repré- sentée par un objet de type list list sous Python. Certaines cases sont déjà remplie par un chiffre de J1, 9K. En Python, nous mettrons 0 dans les cases non remplies. Par exemple, voici une grille complètement vide : [[0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]] Le but est d’inscrire un chiffre de J1, 9K dans chaque case de la grille, en vérifiant les trois règles suivantes : (i) Pour tout i ∈ J0, 8K, les chiffres inscrit sur la ligne i sont deux à deux distincts ; (ii) Pour tout j ∈ J0, 8K, les chiffres inscrit sur la colonne j sont deux à deux distincts ; (iii) La grille étant partagées en 9 blocs carrés de format 3 × 3, les chiffres inscrits dans chaque bloc sont deux à deux distincts. 1. Dans un premier temps, on se concentre sur la fonction principale, qui contient le squelette de l’algo- rithme. On supposera déjà connues les fonctions utilitaires suivantes : • chiffresPossible telle que pour toute grille g et tout (i, j) ∈ J0, 9J2 , chiffresPossible(g,i,j) renvoie la liste des chiffres possibles en case (i, j) de la grille g pour vérifier les trois conditions de la règle du jeu. • prochaineCaseARemplir telle que pour toute grille g, prochaineCaseARemplir(g) renvoie : None si toutes les cases sont déjà remplies (auquel cas la grille est résolue !) un triplet (i, j, listePoss) où (i, j) est une case ayant un minimum de possibilités et listePoss est la liste de ces possibilités dans le cas contraire. 4
  • 5. Écrire alors le programme resolution prenant en entrée une grille g et renvoyant True si cette grille est remplissable et False sinon. En outre, ce programme remplira g au fur et à mesure, de sorte que si il renvoie True, g soit alors complètement remplie. Par contre, si il renvoie False, la grille devra être revenue à son état initial. On propose la stratégie suivante : Utiliser le programme prochaineCaseARemplir pour repérer si la grille est déjà remplie, et dans le cas contraire, identifier la prochaine case à aller remplir ainsi que la liste listePoss des possibilités pour remplir cette case. Pour tout n ∈ listePoss, mettre n dans la case, et reappeler récursivement la fonction resolution. Si cette fonction renvoie True c’est gagné ! Si cette fonction renvoie False c’est qu’il n’a pas été possible de compléter la grille en y mettant n : dans ce cas, effacer n. Si toutes les valeurs de listePoss ont été testées sans succès, c’est qu’il n’est pas possible de remplir la grille. Voir le fichier .py 2. bonus : Écrire les fonctions chiffresPossibles et prochaineCaseARemplir pour obtenir un solveur de sudoku complet. 5