• Aucun résultat trouvé

Informatique Première : Algorithmes de tri Thèmes Projet 1 : Représentation des tris

N/A
N/A
Protected

Academic year: 2022

Partager "Informatique Première : Algorithmes de tri Thèmes Projet 1 : Représentation des tris"

Copied!
11
0
0

Texte intégral

(1)

Informatique Première : Algorithmes de tri

Thèmes

Projet 1 : Représentation des tris

Réaliser une page Web dans laquelle on peut entrer une liste d’entiers à trier. Elle présente un bouton sur lequel on peut cliquer pour voir chaque étape du tri par insertion et un deuxième bouton pour le tri par sélection.

Projet 2 : Performance des tris

Écrire le code Python d’une fonction compare_perf qui prend en paramètres deux entiers N et t et renvoie la durée moyenne, le nombre moyen de comparaisons et le nombre moyen d’affectations (arrondis au dixième) pour N tris par insertion et pour N tris par sélection de listes de longueur t constituées

d’entiers compris entre 1 et 2*t inclus. Donner des valeurs obtenues pours N=100 et t=1000.

Projet 3 : Tri à bulles

Le tri à bulles est une variante du tri par sélection : pour placer le minimum de T[i,…,n-1] dans T[i], on parcourt T[i+1,…,n-1] de n-1 à i+1 et on échange l’élément d’indice j avec celui d’indice j-1 s’ils ne sont pas dans le bon ordre.

Écrire le code Python de la fonction tri_bulles qui prend une liste L en argument et la renvoie après l’avoir triée avec la méthode du tri à bulles.

Démontrer la correction du tri à bulles et comparer ses performances avec celles du tri par sélection.

Méthode proposée

Projet 1

On pourra obtenir la présentation ci-dessous la première ligne dans la colonne des tris est obtenue après avoir cliqué sur le bouton « Enregistrer » et les suivantes par appui sur les deux autres boutons.

Projet 2

Utiliser une fonction perf_tri_insertion qui prend en paramètre une liste L et renvoie le tuple constitué de la durée, du nombre de comparaisons et du nombre d’affectations pour le tri par insertion de la liste L. Utiliser de même une fonction perf_tri_selection. Pour la durée, utiliser la fonction time du module time.

Projet 3

On peut parcourir la liste avec une boucle while et utiliser une variable temp pour garder l’indice du dernier élément échangé. Cette variable est affectée lors du parcours de T[i+1,…,n-1] de n-1 à i+1.

Questions

(2)

Projet 1

On considère le code suivant :

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

22 23

var resultat1=document.querySelector("#r1");

var plage=document.querySelector("#t1");

function test(T){

t=0;

if(T.length>20) t=1;

for(var i=0; i<T.length; i++)

if(isNaN(parseInt(T[i])) || T[i]<0 || T[i]>99) t=1;

return t }

function disposition(c){

if(c.length==1) return "<mark>0</mark>"+c;

return c;

}

var c1=[],texte1="", texte2="", nbreClics1, nbreClics2;

for(var i=0; i<20; i++) c1[i]="black";

document.querySelector("#enr").onclick=function(){

nbreClics1=1; nbreClics2=0;

resultat1.textContent="";

texte1=plage.value.split(",");

for(var i=0; i<texte1.length-1; i++){

resultat1.innerHTML+=

"<span style='color:"+c1[i]+"'>"+disposition(texte1[i])+"</span>, ";

}

resultat1.innerHTML+="<span style='color:"+c1[i]+"'>"

+disposition(texte1[texte1.length-1])+"</span><br/>";

1. Dire quelles sont les valeurs que peut renvoyer la fonction test.

2. Préciser dans quels cas la valeur renvoyée est 1.

3. Écrire le code Python de la fonction test (utiliser try except).

4. Quel est le type des éléments de c1 ?

5. En observant les lignes 2 et 19 et la page Web (dans méthode proposée), donner le code HTML de l’élément qui permet d’entrer la liste à trier

6. Préciser le type de la variable texte1.

7. Expliquer la ligne 19.

8. Expliquer la ligne 21.

9. Expliquer l’intérêt de la ligne 23.

10. En observant la page Web, donner le code CSS appliqué aux balises <mark>.

Projet 2. On considère le code suivant :

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

def perf_tri_selection(L):

t=time()

nbre_affectations=2 nbre_comparaisons=1 n=len(L)

for i in range(n-1):

imin=i

nbre_affectations+=2 nbre_comparaisons+=1 for j in range(i+1,n):

nbre_comparaisons+=1 if L[j]<L[imin]:

nbre_affectations+=1 imin=j

nbre_affectations+=1 nbre_comparaisons+=1 nbre_comparaisons+=1 if imin != i:

nbre_affectations+=3

L[i],L[imin]=L[imin],L[i]

nbre_affectations+=1 nbre_comparaisons+=1 duree=time()-t

return duree,nbre_comparaisons,nbre_affectations

(3)

1. Expliquer la ligne 2.

2. Expliquer comment sont comptées les affectations (lignes 3, 8, 13, 15, 19 et 21).

3. Expliquer comment sont comptées les comparaisons (lignes 4, 9, 11, 16, 17 et 22).

4. Expliquer comment est calculée la durée du tri.

5. Quelles sont les valeurs de

perf_tri_selection([0,1,2])[1]

et

perf_tri_selection([0,1,2])[2]

? 6. Même question avec la liste

[2,1,0]

.

7. Même question avec la liste

[0,1,…,n-2, n-1]

pour n quelconque supérieur ou égal à 3.

8. Si

L=[n-1,n-2,…,1,0]

, dire pour quelles valeurs de i et j les booléens des lignes 12 et 18 sont vrais (distinguer le cas n pair et le cas n impair).

9. Compléter les carrés dans le code suivant :

def perf_tri_insertion(L):

t=time()

nbre_affectations=

nbre_comparaisons=

for i in range(1,len(L)):

j=i-1 k=L[i]

nbre_affectations+=

nbre_comparaisons+=

while j>=0 and L[j]>k:

L[j+1]=L[j]

j=j-1

nbre_affectations+=

nbre_comparaisons+=

L[j+1]=k

nbre_affectations+=

nbre_comparaisons+=

duree=time()-t

return duree,nbre_comparaisons,nbre_affectations

10. Reprendre la question 7 avec la fonction

perf_tri_insertion

. Projet 3

On considère le code suivant :

1 2 3 4 5 6 7 8 9 10 11

def tri_bulles(L):

n=len(L) i=0

while i<n-1:

temp=n-1

for j in range(n-1,i,-1):

if L[j]<L[j-1]:

L[j],L[j-1]=L[j-1],L[j]

temp=j-1 i=temp+1

return L

1. Soit L=[3,1,3,4,5]. Écrire les différentes valeurs prises par L lors de l’exécution de la fonction.

2. Donner les valeurs prises par i si L=[0,1,2,3,4,5].

3. Même question si L=[5,4,3,2,1,0].

4. Expliquer à quoi sert la variable temp.

5. Reprendre le code précédent pour la fonction

perf_tri_bulles

comme dans le projet 2.

6. Quel est, en fonction de n, le nombre de comparaisons et d’affectations si

L=[0,1,…,n-2,n-1]

? 7. Même question si

L=[n-1,n-2,…,1,0]

.

8. Comparer les deux tris par sélection et à bulles en moyenne comme dans le projet 2.

9. Pour la boucle for, montrer l’invariant de boucle P(j) suivant : temp>=j et pour tout k compris entre j et temp inclus, L[k] est le minimum de L[k,…,n-1].

10. Pour la boucle while, montrer l’invariant de boucle Q(i) suivant : la liste L[0,…,i] est triée.

En déduire la correction de l’algorithme.

Corrigé

(4)

Projet 1

1. La fonction test renvoie 0 ou 1.

2. La valeur renvoyée est 1 si la longueur de T est supérieure à 20 (ligne 5) ou si T contient au moins un élément qui n’est pas un entier compris entre 0 et 99 inclus.

3. Code Python :

def test(T):

t=0

if(len(T)>20):

t=1

for i in range(len(T)):

try:

T[i]=int(T[i])

if T[i]<0 or T[i]>99:

t=1 except:

t=1 return t

Remarque. En JS, le test "1"<2 est accepté mais pas en Python.

Pour éviter try et except, on aurait aussi pu utiliser une fonction test qui utilise les codes Unicode des caractères de T[i], ceux-ci devant être compris entre 48 et 57 inclus.

4. Les éléments de c1 sont des chaînes de caractères

5. En observant les lignes 2 et 16 et la page Web (dans méthode proposée), donner le code HTML de l’élément qui permet d’entrer la liste à trier

<p id="p1">Liste à trier (20 entiers naturels de 2 chiffres au maximum) :

<input type="text" id="t1" placeholder="Ex : 1,2,3,4"/><br/>

6. La variable texte1 est un tableau dont les éléments sont des chaînes de caractères.

7. plage.value est une chaîne de caractères. La méthode split avec l’argument "," la découpe en prenant tous les morceaux séparés par des virgules et les place dans le tableau texte1.

8. Le code HTML

<span style='color:"+c1[i]+"'>"+disposition(texte1[i])+"</span>,

est ajouté au contenu de l’élément identifié id="r1". C’est une balise <span> dont le contenu est la chaîne de caractères renvoyée par la fonction disposition avec la couleur c1[i].

9. Cette ligne permet d’éviter d’écrire une virgule dans le dernier <span> c’est-à-dire après le dernier élément de texte1.

10. Les balises <mark> permettent de mettre un espace correspondant à un 0 devant un chiffre (ligne 11).

D’où le code CSS :

mark{color:rgb(20,220,180); background-color:rgb(20,220,180);}, le code rgb(20,220,180) étant celui de la couleur de fond.

Code complet : HTML :

<!DOCTYPE html>

<html>

<head> <meta charset="utf-8"/>

<title>Essai</title>

<link rel="stylesheet" href="style.css"/></head>

<body>

<h1>TRIS PAR INSERTION ET PAR SÉLECTION</h1>

<p id="p1">Liste à trier (20 entiers naturels de 2 chiffres au maximum) : <input type="text" id="t1" placeholder="Ex : 1,2,3,4"/><br/>

Enregistrer après avoir entré la liste.

<input type="button" value="Enregistrer" id="enr"</p>

<p id="p2"><input id="b1" type="button" value="Voir les étapes par

insertion"/><br/>

<input id="b2" type="button" value="Voir les étapes par sélection"/>

</p>

<table>

<tr><td>Tri par insertion</td><td>Tri par sélection</td></tr>

<tr><td><p id="r1"></td><td><p id="r2"></p></td></tr>

</table>

<script src="script.js"></script>

(5)

</body>

</html>

CSS :

body{background-color:rgb(20,220,180);}

mark{color:rgb(20,220,180); background-color:rgb(20,220,180);}

h1{margin-left:100px;}

#b1{margin-bottom:20px;}

#t1{width:380px;}

#p2{position:fixed; top:20px; right:30px;}

#r1{margin-left:30px;}

td{vertical-align:top; text-align:center; border:1px solid;}

table td{padding : 0px 80px; font-family:Consolas;}

JS :

////////////// TRI INSERTION /////////////////////////////////////

var bouton1=document.querySelector("#b1");

var resultat1=document.querySelector("#r1");

var plage=document.querySelector("#t1");

var nbreClics1, nbreClics2;

function tri_insertion(L,i){

for(var m=0; m<20; m++) c1[m]="black";

var j=i-1;

var k=parseInt(L[i]);

while(j>=0 && parseInt(L[j])>k){

L[j+1]=L[j];

j=j-1;

}

L[j+1]=k.toString();

c1[j+1]="red";

return L;

}

function test(T){

t=0;

if(T.length>20) t=1;

for(var i=0; i<T.length; i++)

if(isNaN(parseInt(T[i])) || T[i]<0 || T[i]>99) t=1;

return t }

function disposition(c){

if(c.length==1) return "<mark>0</mark>"+c;

return c;

}

var c1=[];

for(var i=0; i<20; i++) c1[i]="black";

var texte1="", texte2="";

var elt=document.querySelector("#enr");

elt.onclick=function() {

nbreClics1=1; nbreClics2=0;

resultat1.textContent="";

texte1=plage.value.split(",");

for(var i=0; i<texte1.length-1; i++)

resultat1.innerHTML+="<span style='color:"+c1[i]+"'>"+

disposition(texte1[i])+"</span>, ";

resultat1.innerHTML+="<span style='color:"+c1[i]+"'>"+

disposition(texte1[texte1.length-1])+"</span><br/>";

resultat2.innerHTML="";

texte2=plage.value.split(",");

for(var i=0; i<texte2.length-1; i++)

resultat2.innerHTML+="<span style='color:"+c2[i]+"'>"+

disposition(texte2[i])+"</span>, ";

resultat2.innerHTML+="<span style='color:"+c2[i]+"'>"+

disposition(texte2[texte2.length-1])+"</span><br/>";

}

(6)

bouton1.onclick=function(){

texte1=plage.value.split(",");

if(test(texte1)) alert("20 entiers entre 0 et 99 maximum ; \nRecommencer et actualiser la page");

else{

if(nbreClics1<texte1.length) {

texte1=tri_insertion(texte1,nbreClics1);

for(var i=0; i<texte1.length-1; i++){

resultat1.innerHTML+="<span style='color:"+c1[i]+"'>"+

disposition(texte1[i])+"</span>, ";

}

resultat1.innerHTML+="<span style='color:"+c1[i]+"'>"+

disposition(texte1[texte1.length-1])+"</span><br/>";

nbreClics1++;

} }

};

////////////// TRI SELECTION /////////////////////////////////////

var bouton2=document.querySelector("#b2");

var resultat2=document.querySelector("#r2");

function tri_selection(L,i){

for(var m=0; m<20; m++) c2[m]="black";

var imin=i;

var n=L.length;

for(var j=i+1; j<n; j++) if(parseInt(L[j])<parseInt(L[imin])) imin=j;

if(imin!=i) { c2[i]="red";

c2[imin]="red";

var k=L[i];

L[i]=L[imin];

L[imin]=k;

}

else {c2[i]="red";}

return L;

}

var c2=[];

for(var i=0; i<20; i++) c2[i]="black";

bouton2.onclick=function(){

texte2=plage.value.split(",");

if(test(texte2)) alert("Pas plus de 20 entiers ; \nRecommencer et actualiser la page");

else{

if(nbreClics2<texte2.length-1) {

texte2=tri_selection(texte2,nbreClics2);

for(var i=0; i<texte2.length-1; i++)

resultat2.innerHTML+="<span style='color:"+c2[i]+"'>"+

disposition(texte2[i])+"</span>, ";

resultat2.innerHTML+="<span style='color:"+c2[i]+"'>"+

disposition(texte2[texte2.length-1])+"</span><br/>";

nbreClics2++;

} }

};

Projet 2

1. La variable t est un flottant égal au nombre de secondes écoulées entre l’EPOCH (1/1/1970 0h00) et l’instant d’exécution de la ligne de code.

2. Le nombre d’affectations est stocké dans la variable nbre_affectations : ligne 3 pour les lignes 5 et 6 (i=0), ligne 8 pour les lignes 7 et 10 (j=i+1), ligne 13 pour la ligne 14, ligne 15 pour la ligne 10 (j=j+1), ligne 19 pour la ligne 20 (échange de deux variables) et ligne 21 pour la ligne 6

(i=i+1).

(7)

Remarque. On a considéré que for i in range(n): est exécuté comme

i = 0 while i < n:

i = i + 1

3. Le nombre de comparaisons est stocké dans la variable nbre_comparaisons : ligne 4 pour la ligne 6 (i<n-1), ligne 9 pour la ligne 10 (j<n), ligne 11 pour la ligne 12, ligne 16 pour la ligne 10 (j<n), ligne 17 pour la ligne 18 et ligne 22 pour la ligne 6 (i<n-1).

4. C’est la différence entre les deux instants mesurés lignes 2 et 20 avec la fonction time.

5. On trouve

perf_tri_selection([0,1,2])[1]=13

et

perf_tri_selection([0,1,2])[2]=11.

6. De même

perf_tri_selection([2,1,0])[1]=13

et

perf_tri_selection([2,1,0])[2]=16

. 7. Le nombre de comparaisons est

1 + Σ

𝑛−2

𝑖=0

(1 + Σ

𝑛−1

𝑗=𝑖+1

2 + 2) = 1 + Σ

𝑛−2

𝑖=0

(3 + 2(𝑛 − 1 − 𝑖)) = 1 + Σ

𝑛−2

𝑖=0

(1 + 2(𝑛 − 𝑖)) = 𝑛 + 2 Σ

𝑛

𝑘=2

𝑘 = 𝑛 + (𝑛 + 2)(𝑛 − 1) = 𝑛

2

+ 2𝑛 − 2 Lorsque la liste est triée dans l’ordre croissant, le nombre d’affectations est

2 + Σ

𝑛−2

𝑖=0

(2 + Σ

𝑛−1

𝑗=𝑖+1

1 + 1) = 2 + Σ

𝑛−2

𝑖=0

(𝑛 − 𝑖 + 2) = 2 + Σ

𝑛+2

𝑘=4

𝑘 =

(𝑛+2)(𝑛+3)

2

− 4 car le booléen de la ligne 12 est toujours faux.

8. Si 𝑛 = 2𝑘, la liste est triée quand 𝑖 ≥ 𝑘 et, si 𝑖 ≤ 𝑘 − 1, le booléen de la ligne 12 est vrai pour 𝑖 + 1 ≤ 𝑗 ≤ 2𝑘 − 𝑖 − 1. Dans ce cas le booléen de la ligne 18 est vrai et sinon il est faux :

Indices 0 … i-1 i … k-1 k … 2k-1-i 2k-i … 2k-1

Valeurs avant

classement 2k-1 … 2k-i 2k-i-1 … k k-1 … i i-1 … 0 Valeurs pour

i<=k-1 fixé 0 … i-1 2k-i-1 … k k-1 … i 2k-i … 2k-1

Remarque. On peut donc calculer le nombre d’affectations : 2 + Σ𝑘−1

𝑖=0(2+2𝑘−1−𝑖Σ

𝑗=𝑖+12+ 2𝑘−1Σ

𝑗=2𝑘−𝑖1+ 4) + Σ2𝑘−2

𝑖=𝑘 (2+2𝑘−1Σ

𝑗=𝑖+11+1)

= 2 +2𝑘+ Σ𝑘−1

𝑖=0(2(2𝑘 − 1 − 2𝑖)+𝑖+ 4) +3(𝑘 − 1)+ Σ2𝑘−2

𝑖=𝑘(2𝑘 − 1 − 𝑖)

= 2 + 2𝑘 + 2𝑘(2𝑘 − 1) − 2𝑘(𝑘 − 1) +𝑘(𝑘−1)

2 + 4𝑘 + 3𝑘 − 3 + (2𝑘 − 1)(𝑘 − 1) − (𝑘 − 1)(3𝑘−2)

2

= 3𝑘2+ 8𝑘 − 1 =3

4𝑛2+ 4𝑛 − 1

De même si 𝑛 = 2𝑘 + 1, la liste est triée quand 𝑖 ≥ 𝑘 et, si 𝑖 ≤ 𝑘 − 1, le booléen de la ligne 12 est vrai pour 𝑖 + 1 ≤ 𝑗 ≤ 2𝑘 − 𝑖. Dans cas le booléen de la ligne 18 est vrai et sinon il est faux.

Remarque. On peut donc calculer le nombre d’affectations : 2 + Σ𝑘−1

𝑖=0(2 + Σ2𝑘−𝑖

𝑗=𝑖+12 + 2𝑘Σ

𝑗=2𝑘−𝑖+11 + 4) + Σ2𝑘−1

𝑖=𝑘 (2 + Σ2𝑘

𝑗=𝑖+11 + 1)

= 2 + 2𝑘 + Σ𝑘−1

𝑖=0(2(2𝑘 − 2𝑖) + 𝑖 + 4) + 2𝑘 + Σ2𝑘−1

𝑖=𝑘(2𝑘 − 𝑖) + 𝑘

= 2 + 2𝑘 + 2𝑘(2𝑘) − 2𝑘(𝑘 − 1) +𝑘(𝑘−1)

2 + 4𝑘 + 2𝑘 + (2𝑘)(𝑘) − (𝑘)(3𝑘−1)

2 + 𝑘

= 3𝑘2+ 11𝑘 + 2 = 3 (𝑛−1

2 )2+ 11 (𝑛−1

2 ) + 2 =3

4𝑛2+ 4𝑛 −11

4.

Le nombre de comparaisons est le même qu’à la question précédente dans les deux cas.

9. Dans l’ordre : 1 (pour i=1), 1 (pour i<len(L)), 2 (pour j et k), 2 (pour j>=0 et L[j]>k), 2 (pour L[j+1] et j), 2 (pour j>=0 et L[j]>k), 1 (pour L[j+1]), 1 (pour i<len(L)).

10. Dans le cas où la liste est déjà triée, on n’entre jamais dans la boucle while donc le nombre de comparaisons et d’affectations est 1 +

𝑛−1Σ

𝑖=13 = 1 + 3

(

𝑛 − 1

)

= 3𝑛 − 2 .

Le coût est donc linéaire dans le meilleur des cas.

Code complet :

from random import randint from time import time def perf_tri_insertion(L):

t=time()

nbre_affectations=1 #i=1 nbre_comparaisons=1 #i<len(L)

(8)

for i in range(1,len(L)):

j=i-1 k=L[i]

nbre_affectations+=2 #j et k

nbre_comparaisons+=2 #j>=0 et L[j]>k while j>=0 and L[j]>k:

L[j+1]=L[j]

j=j-1

nbre_affectations+=2 #L[j+1] et j nbre_comparaisons+=2 #j>=0 et L[j]>k L[j+1]=k

nbre_affectations+=1 #L[j+1]

nbre_comparaisons+=1 #i<len(L) duree=time()-t

return duree,nbre_comparaisons,nbre_affectations

def perf_tri_selection(L):

t=time()

nbre_affectations=2 #n=len(L) et i=0 nbre_comparaisons=1 #i<n-1

n=len(L)

for i in range(n-1):

imin=i

nbre_affectations+=2 #imin et j=i+1 nbre_comparaisons+=1 #j<n

for j in range(i+1,n):

nbre_comparaisons+=1 #L[j]<L[imin]

if L[j]<L[imin]:

nbre_affectations+=1 #imin imin=j

nbre_affectations+=1 #j=j+1 nbre_comparaisons+=1 #j<n nbre_comparaisons+=1 #imin!=i if imin != i:

nbre_affectations+=3 #échange L[i],L[imin]=L[imin],L[i]

nbre_affectations+=1 #i=i+1 nbre_comparaisons+=1 #i<n-1 duree=time()-t

return duree,nbre_comparaisons,nbre_affectations

def compare_perf(N,t):

"""

compare les deux algorithmes sur N tris de listes de longueur t (entiers entre 1 et 2*t) """

duree_ins=0

nbre_comparaisons_ins=0 nbre_affectations_ins=0 duree_sel=0

nbre_comparaisons_sel=0 nbre_affectations_sel=0

for i in range(N):

L=[]

for j in range(t):

L.append(randint(1,2*t)) T_ins=perf_tri_insertion(L) T_sel=perf_tri_selection(L) duree_ins+=T_ins[0]

nbre_comparaisons_ins+=T_ins[1]

nbre_affectations_ins+=T_ins[2]

duree_sel+=T_sel[0]

nbre_comparaisons_sel+=T_sel[1]

nbre_affectations_sel+=T_sel[2]

(9)

return round(duree_ins/N,1),round(nbre_comparaisons_ins/N,1),

round(nbre_affectations_ins/N,1), round(duree_sel/N,1),

round(nbre_comparaisons_sel/N,1),round(nbre_affectations_sel/N,1) print(compare_perf(100,1000))

Les trois lignes après return doivent être écrites sur une seule ligne.

On trouve par exemple, après quelques dizaines de secondes :

(0.1, 502036.3, 502036.3, 0.2, 1001998.0, 502499.0)

On a donc trié 100 listes de 1000 entiers compris entre 1 et 2000 en 0,1 s en moyenne avec le tri par insertion et en 0,2 s en moyenne avec le tri par sélection.

Le coût moyen par insertion est de 502 036 affectations et comparaisons. Par sélection le nombre d’affectations est du même ordre mais le nombre de comparaisons est doublé.

Projet 3

1. On a n=6. Les différentes étapes sont :

i=0 : [3,1,3,4,2,5] (temp=5), [3,1,3,2,4,5] (temp=3), [3,1,2,3,4,5] (temp=2), [1,3,2,3,4,5] (temp=0)

i=1 : [1,2,3,3,4,5] (temp=1) i=2 : temp=5

2. Pour i=0, la condition

L[j]<L[j-1]

est fausse donc temp reste égal à n-1 si bien qu’à la ligne 10, on a i=n-1 et la boucle se termine. La variable i ne prend donc que deux valeurs : 0 et n-1.

3. Cette fois-ci la condition

L[j]<L[j-1] est toujours vraie donc, à la ligne 10, on a i=i+1 si bien que i prend toutes les valeurs entre 0 et n-1 inclus.

4. Sans la variable temp, la variable i prend toutes les valeurs entre 0 et n-2 inclus. La variable temp permet de ne pas comparer plusieurs fois L[j] et L[j-1] ; en effet, pour i+1<j<temp on a

nécessairement L[j]>=L[j-1] ce qui signifie que les éléments sont dans le bon ordre. On peu donc passer directement à i=temp.

5.

def perf_tri_bulles(L):

t=time() n=len(L) i=0

nbre_affectations=2 #n et i nbre_comparaisons=1 #i<n while i<n:

temp=n

nbre_affectations+=2 #temp et j=n-1 for j in range(n-1,i,-1):

nbre_comparaisons+=1 #L[j]<L[j-1]

if L[j]<L[j-1]:

L[j],L[j-1]=L[j-1],L[j]

temp=j

nbre_affectations+=4 #temp et échange nbre_affectations+=1 #j=j-1

nbre_comparaisons+=1 #j>i i=temp

nbre_affectations+=1 #i nbre_comparaisons+=1 #i<n duree=time()-t

return duree,nbre_comparaisons,nbre_affectations

6. Lorsque la liste est triée dans l’ordre croissant, la boucle while n’est exécutée qu’une seule fois avec i=0 et la condition L[j]<L[j-1] est fausse (voir 1) donc le nombre de comparaisons est

1 + 2(𝑛 − 1) + 1 = 2𝑛 et le nombre d’affectations est 2 + 2 + (𝑛 − 1) + 1 = 𝑛 + 4.

7. Lorsque la liste est triée dans l’ordre décroissant, la boucle while est exécutée pour tous le entiers i et la condition L[j]<L[j-1] est toujours vraie (voir 2) donc le nombre de comparaisons est

1 + Σ

𝑛−1

𝑖=0

( Σ

𝑛−1

𝑗=𝑖+1

2 + 1) = 1 + Σ

𝑛−1

𝑖=0

(2(𝑛 − 1 − 𝑖) + 1) = 1 + 2 Σ

𝑛−1

𝑖=0

(𝑛 − 𝑖) − 𝑛 = 1 + 2 Σ

𝑛

𝑘=1

𝑘 − 𝑛 = 1 + 𝑛(𝑛 + 1) − 𝑛 = 𝑛

2

+ 1

(10)

De même, le nombre d’affectations est 2 + Σ

𝑛−1

𝑖=0

(2 + Σ

𝑛−1

𝑗=𝑖+1

5 + 1) = 2 + Σ

𝑛−1

𝑖=0

(5(𝑛 − 1 − 𝑖) + 3) = 2 + 5 Σ

𝑛−1

𝑖=0

(𝑛 − 𝑖) − 2𝑛 = 2 + 5 Σ

𝑛

𝑘=1

𝑘 − 2𝑛 = 2 +

5

2

𝑛(𝑛 + 1) − 2𝑛 =

5

2

𝑛

2

+

1

2

𝑛 + 2 8. On trouve par exemple :

(0.4, 993669.6, 1497668.4, 0.2, 1001998.0, 502499.0)

avec 0,4 s pour le tri à bulles et 0,2 s pour le tri par sélection.

9. Initialisation. Pour j=n-1, on a temp=n-1 et L[n-1] est bien le minimum de L[n-1].

Conservation. Supposons P(j) vrai pour j entre i+1 et n-1 inclus. Alors à l’issue de l’itération, on a j=j-1 et temp>=j-1car temp>=j au début de l’itération et temp=j-1 si le booléen de la ligne 7 est vrai.

De plus, pour tout k compris entre j et temp inclus, L[k] est le minimum de L[k,…,n-1] par hypothèse initiale et d’près le booléen de la ligne 7, L[j-1] est encore le minimum de

L[j-1,…,n-1]

puisqu’on échange L[j] et L[j-1] s’ils ne sont pas dans le bon ordre.

Terminaison. La dernière valeur de j est i+1 donc à l’issue de la boucle, L[i] est le minimum de L[i,…,n-1].

10. Initialisation. Pour i=0, la liste L[0,…,i] est réduite à L[0] donc elle est triée.

Conservation. Supposons Q(i) vrai pour i entre 0 et n-2 inclus. Alors, d’après 8, à l’issue de l’itération L[i] est le minimum de L[i,…,n-1] et, comme L[0,…,i] est triée, il en est de même de L[0,…, i+1].

Terminaison. La dernière valeur de i est n-2 donc à l’issue de la boucle, la liste L[0,…,n-1] est triée ce qui montre la correction de l’algorithme.

Code complet :

from time import time from random import randint def tri_bulles(L):

n=len(L) i=0

while i<n:

temp=n

for j in range(n-1,i,-1):

if L[j]<L[j-1]:

L[j],L[j-1]=L[j-1],L[j]

temp=j i=temp

return L

def perf_tri_bulles(L):

t=time() n=len(L) i=0

nbre_affectations=2 #n et i nbre_comparaisons=1 #i<n while i<n:

temp=n

nbre_affectations+=2 #temp et j=n-1 for j in range(n-1,i,-1):

nbre_comparaisons+=1 #L[j]<L[j-1]

if L[j]<L[j-1]:

L[j],L[j-1]=L[j-1],L[j]

temp=j

nbre_affectations+=4 #temp et échange nbre_affectations+=1 #j=j-1

nbre_comparaisons+=1 #j>i i=temp

nbre_affectations+=1 #i nbre_comparaisons+=1 #i<n duree=time()-t

return duree,nbre_comparaisons,nbre_affectations

(11)

def perf_tri_selection(L):

t=time()

nbre_affectations=2 #n=len(L) et i=0 nbre_comparaisons=1 #i<n-1

n=len(L)

for i in range(n-1):

imin=i

nbre_affectations+=2 #imin et j=i+1 nbre_comparaisons+=1 #j<n

for j in range(i+1,n):

nbre_comparaisons+=1 #L[j]<L[imin]

if L[j]<L[imin]:

nbre_affectations+=1 #imin imin=j

nbre_affectations+=1 #j=j+1 nbre_comparaisons+=1 #j<n nbre_comparaisons+=1 #imin!=i if imin != i:

nbre_affectations+=3 #échange L[i],L[imin]=L[imin],L[i]

nbre_affectations+=1 #i=i+1 nbre_comparaisons+=1 #i<n-1 duree=time()-t

return duree,nbre_comparaisons,nbre_affectations

def compare_perf(N,t):

duree_bul=0

nbre_comparaisons_bul=0 nbre_affectations_bul=0 duree_sel=0

nbre_comparaisons_sel=0 nbre_affectations_sel=0

for i in range(N):

L=[]

for j in range(t):

L.append(randint(1,2*t)) T_bul=perf_tri_bulles(L) T_sel=perf_tri_selection(L) duree_bul+=T_bul[0]

nbre_comparaisons_bul+=T_bul[1]

nbre_affectations_bul+=T_bul[2]

duree_sel+=T_sel[0]

nbre_comparaisons_sel+=T_sel[1]

nbre_affectations_sel+=T_sel[2]

return round(duree_bul/N,1), round(nbre_comparaisons_bul/N,1),

round(nbre_affectations_bul/N,1),

round(duree_sel/N,1), round(nbre_comparaisons_sel/N,1),

round(nbre_affectations_sel/N,1)

Les quatre lignes après return doivent être écrites sur une seule ligne.

Références

Documents relatifs

— Cette échelle permet de construire, tiès simplement, la perspective d'une figure, connaissant les coordonnées de ces points par rapport à deux axes du plan, l'un étant une

Si le nombre de participants est inférieur ou égale à 50 l’aide sera de 80€ par personne sinon elle ne sera plus que de 50€ par participant.. On souhaite écrire un algorithme

4 Écris chaque nombre sous forme décimale puis en notation

Soit C n le nombre moyen de comparaisons effectuées par l’algorithme de tri rapide (voir algo- rithme 1) sur un tableau uniformément distribué de taille

Exceptions : des pneus, des bleus Les noms terminés par ou ont leur pluriel en

Exceptions : bail, émail, corail, soupirail, travail, vitrail, vantail font leur pluriel en aux. Les noms terminés par x, s ou z ne changent pas au pluriel

Le diagramme en bâtons ci-contre donne le nombre de buts marqués lors de la seconde édition de la coupe de l’Outre-Mer de football?. Combien de buts l’équipe de Mayotte

- Pour la recomposition du tableau, il n'est pas possible d'évaluer a priori le nombre de passage dans la boucle interne ( pour cpt … ) puisque cette boucle dépend des valeurs