Proposition de corrigé, Métropole 2024 J1
Le sujet est téléchargeable ici. Il contient quelques erreurs, mais une seule a été signalée lors de l'épreuve :
- Exercice 1, sur le graphe, la pondération entre le
site 1et lesite 5doit être corrigée en remplaçant2par3. - Pour les autres erreurs du sujet, plusieurs interprétations sont possibles et j'essayerai d'être le plus exhaustif possible.
Exercice 1
Le graphe et le code fournis dans l'énoncé

La classe Site ;
1 2 3 4 5 6 7 8 9 10 | |
La représentation du graphe avec la classe Site :
1 2 3 4 5 6 7 8 9 10 11 12 | |
- Le site
site2n'est cité par aucun autre site (il n'y a pas d'arc entrant sur le noeudsite2). Il ne possède pas de prédécesseurs d'où l'affectation d'une liste vide às2.predecesseurs. -
Lignes 11 et 12 :
11 12
s4.predecesseurs = [(s1, 1), (s2, 2)] # ou bien l'ordre inverse des éléments de la liste s5.predecesseurs = [(s1, 3), (s3, 3), (s4, 6)] # ou tout autre ordre des éléments de la liste -
s2.successeursest de typelist, doncs2.successeurs[1]est l'élément d'indice1de la liste, soit le tuple(s3, 5). D'oùs2.successeurs[1][1]est l'élément d'indice1du tuple, soit l'élément5de typeint. -
Selon la définition, le site
site1possède deux prédécesseurs,site2avec4citations etsite4avec2citations. la popularité desite1est donc4+2 = 6. -
Le code de la méthode, avec tuple unpacking :
10 11 12 13 14
def calculPopularite(self): self.popularite = 0 for site, pop in self.predecesseurs : self.popularite += pop return self.populariteLe code du parcours du graphe
1 2 3 4 5 6 7 8 9 10 11 12 13 14
def parcoursGraphe(sommetDepart): parcours = [] sommetDepart.couleur = 'noire' listeS = [] listeS.append(sommetDepart) while len(listeS) != 0: site = listeS.pop(0) site.calculPopularite() parcours.append(site) for successeur in site.successeurs: if successeur[0].couleur == 'blanche': successeur[0].couleur = 'noire' listeS.append( successeur[0] ) return parcours -
Lorsqu'on ajoute un élément à
listeSavecappend, celui-ci est mis à la fin de la liste. Lorsqu'on retire un élément avecpop(0), il s'agit de l'élément d'indice0, soit le premier inséré. On est donc sur une structure de typePEPS(FIFO), c'est-à-dire une file. -
C'est un parcours en largeur du graphe (on parcourt un sommet, puis tous ses successeurs, puis tous les successeurs de ceux-ci, etc. ).
-
À l'appel de
parcoursGraphe(s1):s1est le premier sommet inséré dansparcours;- puis on ajoute tous ses successeurs dans l'ordre de son attribut
successeurs, soits3,s4puiss5; - on ajoute ensuite les successeurs de
s3qui ne sont pas de couleur noire, il ne reste plus ques2, et ainsi tous les noeuds sont marqués.
Donc l'appel
parcoursGraphe(s1)renvoie la liste[s1, s3, s4, s5, s2]. -
Complétion des lignes 6 et 7 du code fourni :
1 2 3 4 5 6 7 8
def lePlusPopulaire(listeSites): maxPopularite = 0 siteLePlusPopulaire = listeSites[0] for site in listeSites: if site.popularite > maxPopularite: maxPopularite = site.popularite siteLePlusPopulaire = site return siteLePlusPopulaire -
En calculant la popularité de chaque site, on obtient :
Site s1s2s3s4s5Popularité 6 0 12 3 12 Or la fonction
lePlusPopulairerenvoie le premier site trouvé ayant la plus grande popularité (ceci est du au signe>ligne5. Si le signe avait été>=, la fonction aurait renvoyé le dernier site trouvé avec la plus grande popularité).Donc d'après l'ordre de parcours donné en question 8, l'appel
lePlusPopulaire(parcoursGraphe(s1)).nomrenvoie la chaine de caractères'site3'. -
En utilisant la fonction
parcoursGraphe:* on va parcourir l'ensemble du graphe ; * à chaque étape on doit ré-indexer l'ensemble des éléments de `listeS`, qui est utilisé comme une file ;donc la complexité en temps de la fonction
parcoursGrapheest en \(\mathscr{O}(n^2)\). De plus la fonctionlePlusPopulaireest en \(\mathscr{O}(n)\).L'utilisation de ces fonctions n'est donc pas efficace. Il faudrait utiliser une véritable structure de file, et ne faire qu'un parcours, en intégrant la recherche du site le plus populaire dans la fonction de parcours du graphe.