254 lines
5.4 KiB
Python
254 lines
5.4 KiB
Python
#!/usr/bin/python3
|
||
# -*- coding: utf-8 -*-
|
||
|
||
"""
|
||
TP AP1
|
||
Licence SESI 1ère année
|
||
Univ. Lille 1
|
||
|
||
analyse_tris.py
|
||
|
||
TP4 - Evaluation empirique des tris
|
||
|
||
http://www.fil.univ-lille1.fr/~L1S2API/CoursTP/tp4_tri.html
|
||
|
||
"""
|
||
|
||
__author__ = 'PREUD\'HOMME Geoffrey & BEAUSSART Jean-loup'
|
||
__date_creation__ = 'Tue, 10 Mar 2015 10:26:41 +0100'
|
||
|
||
from random import randint
|
||
|
||
|
||
def partie(nom):
|
||
print('\n', nom, '=' * len(nom), sep='\n')
|
||
|
||
|
||
def section(nom):
|
||
print('\n', nom, '-' * len(nom), sep='\n')
|
||
|
||
|
||
def question(numero):
|
||
print('\n***', 'Question', numero, '***')
|
||
|
||
partie("Prérequis")
|
||
|
||
|
||
def comp(x, y):
|
||
"""
|
||
parametres
|
||
x , y de même type et comparables
|
||
valeur renvoyee : int
|
||
-1 si x<y
|
||
0 si x==y
|
||
1 si x>y
|
||
action : incrémente le compteur
|
||
CU : aucune
|
||
"""
|
||
global compteur
|
||
compteur = compteur + 1
|
||
if x < y:
|
||
return -1
|
||
elif x == y:
|
||
return 0
|
||
else:
|
||
return 1
|
||
|
||
|
||
def select_min(l, a, b):
|
||
"""
|
||
list, int, int → int
|
||
Renvoie l'indicde d'un élément minimal de la tranche l[a:b]
|
||
CU : l est une liste de longueur n, d'éléments homogènes ordonnables, et a et b deux indices tels
|
||
que 0 ≤ a < b < n
|
||
"""
|
||
assert 0 <= a < b <= len(l)
|
||
|
||
imin = a
|
||
for i in range(a + 1, b + 1):
|
||
if comp(l[i], l[imin]) == -1:
|
||
imin = i
|
||
return imin
|
||
|
||
|
||
def tri_selection(l):
|
||
"""
|
||
list → ∅
|
||
La liste l est trié (selon l'algorithme du tri par sélection du minimum)
|
||
CU : l est une liste de longueur n, homogène, d’éléments ordonnables
|
||
"""
|
||
n = len(l)
|
||
for i in range(n - 1):
|
||
imin = select_min(l, i, n - 1)
|
||
l[i], l[imin] = l[imin], l[i]
|
||
|
||
|
||
def tri_insertion_base(l, n):
|
||
"""
|
||
list, int → ∅
|
||
n est un indice de l tel que l[0:n] soit une liste triée. La fonction déplace l'élément de rang n de telle sorte que l[0:i+1] soit triée
|
||
CU: n est un entier < len(l) et l est une liste, dont les éléments sont comparables, triée jusqu'à l'indice n-1.
|
||
"""
|
||
|
||
assert(type(n) == int and type(l) == list and n < len(l))
|
||
|
||
aux = l[n]
|
||
|
||
k = n
|
||
while k >= 1 and comp(l[k - 1], aux) == 1:
|
||
l[k] = l[k - 1]
|
||
k -= 1
|
||
|
||
l[k] = aux
|
||
|
||
|
||
def tri_insertion(l):
|
||
for i in range(1, len(l)):
|
||
tri_insertion_base(l, i)
|
||
|
||
partie("Travail à réaliser")
|
||
|
||
section("Préliminaires")
|
||
|
||
question(1)
|
||
|
||
|
||
def liste_croissante(n):
|
||
"""
|
||
int → list(int)
|
||
Retourne la liste des entiers compris entre 0 et n-1, rangés dans l'ordre croissant
|
||
CU: n est un entier positif
|
||
"""
|
||
assert(type(n) == int and n >= 0)
|
||
|
||
return [i for i in range(n)]
|
||
|
||
|
||
question(2)
|
||
|
||
|
||
def liste_decroissante(n):
|
||
"""
|
||
int → list(int)
|
||
Retourne la liste des entiers compris entre 0 et n-1, rangés dans l'ordre décroissant
|
||
CU: n est un entier positif
|
||
"""
|
||
assert(type(n) == int and n >= 0)
|
||
|
||
return [i for i in range(n - 1, 0, -1)]
|
||
|
||
question(3)
|
||
|
||
|
||
def liste_alea(n, a, b):
|
||
"""
|
||
int, int, int → list
|
||
Renvoie une liste d’entiers, qui construit une liste de longueur n les entiers choisis au hasard
|
||
compris entre a et b.
|
||
"""
|
||
res = []
|
||
for i in range(n):
|
||
res.append(randint(a, b))
|
||
return res
|
||
|
||
section("Compter les comparaisons")
|
||
|
||
question(1)
|
||
|
||
compteur = 0
|
||
|
||
tri_selection(liste_alea(100, -5000, 5000))
|
||
|
||
print(compteur, 'comparaisons')
|
||
|
||
question(2)
|
||
|
||
|
||
def tri_et_compte(foo, l):
|
||
"""
|
||
Trie la liste l avec la fonction de triage foo passée en paramètre, renvoie la liste triée et le nombre de comparaisons effectuées
|
||
str, list → (list, int)
|
||
CU: l est une liste
|
||
"""
|
||
|
||
assert(type(l) == list)
|
||
|
||
global compteur
|
||
|
||
compteur = 0
|
||
foo(l)
|
||
|
||
return (l, compteur)
|
||
|
||
partie("Analyse du tri par sélection")
|
||
|
||
|
||
def afficher_tableau(donnees):
|
||
"""
|
||
list[list] → ∅
|
||
Affiche donnees sous forme d'un tableau x / y
|
||
CU : donnees est une liste contenant des listes de même longueurs
|
||
"""
|
||
taillesColonnes = []
|
||
for x in range(len(donnees[0])):
|
||
tailles = []
|
||
for y in range(len(donnees)):
|
||
tailles.append(len(str(donnees[y][x])))
|
||
taillesColonnes.append(max(tailles))
|
||
barres = ['─'*l for l in taillesColonnes]
|
||
print('┌' + '┬'.join(barres) + '┐')
|
||
for y in range(len(donnees)):
|
||
ligne = '│'
|
||
for x in range(len(donnees[0])):
|
||
ligne += ' ' * (taillesColonnes[x] - len(str(donnees[y][x]))) + str(donnees[y][x]) + '│'
|
||
print(ligne)
|
||
if y == 0:
|
||
print('├' + '┼'.join(barres) + '┤')
|
||
print('└' + '┴'.join(barres) + '┘')
|
||
|
||
question(1)
|
||
|
||
tableau = [['i', 'croissante ', 'decroissante', 'aléatoire ']]
|
||
for i in range(2, 102):
|
||
tableau.append([i - 1, tri_et_compte(tri_selection, liste_croissante(i))[1], tri_et_compte(
|
||
tri_selection, liste_decroissante(i))[1], tri_et_compte(tri_selection, liste_alea(i, 0, 500))[1]])
|
||
afficher_tableau(tableau)
|
||
|
||
question(2)
|
||
|
||
partie("Analyse du tri par insertion")
|
||
|
||
question(1)
|
||
|
||
for i in range(2, 102):
|
||
print(i - 1, " ", tri_et_compte(tri_insertion, liste_croissante(i))[1], " ", tri_et_compte(
|
||
tri_insertion, liste_alea(i, 0, 500))[1], " ", tri_et_compte(tri_insertion, liste_decroissante(i))[1])
|
||
|
||
section("Dans le meilleur des cas")
|
||
|
||
question(1)
|
||
|
||
question(2)
|
||
|
||
section("Dans le pire des cas")
|
||
|
||
question(1)
|
||
|
||
question(2)
|
||
|
||
section("En moyenne")
|
||
|
||
question(1)
|
||
|
||
question(2)
|
||
|
||
question(3)
|
||
|
||
question(4)
|
||
|
||
question(5)
|
||
|
||
section("Avec Gnuplot")
|
||
|
||
question(1)
|