#!/usr/bin/python3 # -*- coding: utf-8 -*- # pylint: disable=invalid-name, global-statement """ 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): """ str → ∅ Affiche le nom de la partie en cours """ assert type(nom) == str print('\n', nom, '=' * len(nom), sep='\n') def section(nom): """ str → ∅ Affiche le nom de la section en cours """ assert type(nom) == str print('\n', nom, '-' * len(nom), sep='\n') def question(numero): """ str → ∅ Affiche le numéro de la question en cours """ assert type(numero) == int 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 xy 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 """ assert type(l) == list 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 0 <= 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): """ list → ∅ La liste l est trié (selon l'algorithme du tri par insertion) CU : l est une liste de longueur n, homogène, d’éléments ordonnables """ assert type(l) == list 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 list(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 list(range(n - 1, -1, -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. CU : n entier positif, a et b entiers, a ≤ b """ assert type(n) == type(a) == type(b) == int and n >= 0 and a <= b return [randint(a, b) for _ in range(n)] section("Compter les comparaisons") question(1) compteur = 0 tri_selection(liste_alea(100, -5000, 5000)) print('{} comparaisons ont été faite pour cette liste.'.format(compteur)) question(2) def tri_et_compte(trieur, l): """ Trie la liste l avec la fonction de triage trieur passée en paramètre, renvoie la liste triée et le nombre de comparaisons effectuées str, list → (list, int) CU: trieur est une fonction, l est une liste """ assert callable(trieur) and type(l) == list global compteur compteur = 0 ltrie = trieur(l[:]) # On fait une copie l return (ltrie, 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 = [max([len(str(donnees[y][x])) for y in range( len(donnees))]) for x in range(len(donnees[0]))] 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 = [['nb ', 'croissante ', 'aléatoire ', 'decroissante']] for nb in range(1, 101): tableau.append([nb, tri_et_compte(tri_selection, liste_croissante(nb))[1], tri_et_compte(tri_selection, liste_alea(nb, 0, 500))[1], tri_et_compte(tri_selection, liste_decroissante(nb))[1]]) afficher_tableau(tableau) question(2) partie("Analyse du tri par insertion") question(1) tableau = [tableau[0]] for nb in range(1, 101): tableau.append([nb, tri_et_compte(tri_insertion, liste_croissante(nb))[1], tri_et_compte(tri_insertion, liste_alea(nb, 0, 500))[1], tri_et_compte(tri_insertion, liste_decroissante(nb))[1]]) afficher_tableau(tableau) section("Dans le meilleur des cas") question(1) print("Le meilleur des cas est lorsque la liste est déjà triée.") question(2) tableau = [['i', 'coût comtpé', 'coût théor.', 'fidèle']] tousFideles = True for nb in range(1, 101): c_compte = tri_et_compte(tri_insertion, liste_croissante(nb))[1] c_theor = nb-1 fidele = c_compte == c_theor if not fidele: tousFideles = False tableau.append([nb, c_compte, c_theor, fidele]) afficher_tableau(tableau) print("Les résultats comptés {} tous fidèles aux résultats théoriques." .format("sont" if tousFideles else "ne sont pas")) 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)