Docker-in-Docker (DinD) capabilities of public runners deactivated. More info

Commit 735e5c6b authored by Cyril L'Orphelin's avatar Cyril L'Orphelin
Browse files

TP4 : restructuration du TP

parent 31e4544d
# -*- coding: utf-8 -*-
"""
Comparaison des performances de plusieurs algorithmes de tri écrit en Python
\n tri par selection
\n tri par selection récursif
\n tri par insertion
\n tri fusion
\n tri bulle
\n tri rapide
:author: cyril
:copyright: cnrs
"""
import random
import timeit
def tri_selection(tab, longueur):
"""
Tri par sélection \n
On détermine la position du plus petit élément, on le met en première
position et on itère le procédé sur le tableau restant. \n
Complexité en 0(lgn2) dans tous les cas.
:param tab: tableau à trier
:type tab: array
:param longueur: taille du tableau
:return: tableau trié
:rtype: array
"""
if longueur < 2:
# Moins de 2 éléments : pas besoin de trier
return tab
for index in range(longueur - 1):
# On suppose que le min est en premier
mini = tab[index]
imin = index
for j in range(index + 1, longueur):
if tab[j] < mini:
# On met à jour le mini
mini = tab[j]
imin = j
if imin != index:
# On pertmute pour mettre le min en premier
tab[imin] = tab[index]
tab[index] = mini
return tab
def tri_recursif(tab, longueur):
"""
Tri par sélection récursif\n
On détermine la position du plus grand élément et on le met en dernière
position. On réappelle alors la fonction tri_recursif sur le sous tableau
composé des n-1 premiers éléments de t.\n
Complexité en O(n**2) dans tous les cas.
:param tab: tableau à trier
:type tab: array
:param longueur: taille du tableau
:return: tableau trié
:rtype: array
"""
if longueur < 2:
# Moins de 2 éléments : pas besoin de trier
return tab
# On suppose que le max est en dernier
maxi = tab[longueur - 1]
imax = longueur - 1
for index in range(longueur - 2):
if tab[index] > maxi:
# On met à jour le max
maxi = tab[index]
imax = index
if imax != longueur - 1:
# On permute pour mettre le max en dernier
tab[imax] = tab[longueur - 1]
tab[longueur - 1] = maxi
# Appel de tri_recursif sur t de taille n-1 pour trier le reste du tableau
tab = tri_recursif(tab, longueur - 1)
return tab
def tri_insertion(tab, longueur):
"""
Tri par insertion\n
On ordonne les deux premiers éléments.\n
On insère le 3ème de manière à ce que les 3 soient ordonnés.\n
On insère le i-ème de manière à ce que les i éléments soient ordonnées.\n
La complèxité est en O(n**2) dans le pire des cas.\n
:param tab: tableau à trier
:type tab: array
:param longueur: taille du tableau
:return: tableau trié
:rtype: array
"""
if longueur < 2:
# Moins de 2 éléments : pas besoin de trier
return tab
for index in range(1, longueur):
item = tab[index] # un élément de la t
j = index - 1
# tant qu'on n'a pas atteint le début ou un élément plus petit
while j >= 0 and item < tab[j]:
tab[j+1] = tab[j] # on décale l'élément trouvé vers la droite
j = j - 1
tab[j+1] = item # on insere item a sa place
return tab
def tri_fusion(tab, longueur):
"""
Tri fusion\n
On découpe le tableau à trier en deux sous-tableaux de taille n/2.
On trie alors les deux sous-tableaux récursivement, ou on ne fait rien
s'ils sont de taille 1.\n
On reconstitue le tableau trié initial en fusionnant les deux sous-tableaux
triés.\n
La complexité est en O(n*log(n)) dans le pire des cas.\n
:param tab: tableau à trier
:type tab: array
:param longueur: taille du tableau
:return: tableau trié
:rtype: array
"""
def vidage(ta, pa, na, tab, pos):
"""
Copie ta de taille na à partir de la position pa dans t à partir de p
:param ta: tableau à copier
:param pa: position à partir de laquelle copier
:param na: taille de ta
:param tab: tableau de destination
:param p: position à partir de laquelle coller
:return:
"""
for index in range(pa, na):
tab[pos] = ta[index]
pos += 1
return tab
if longueur < 2:
# Moins de 2 éléments : pas besoin de trier
return tab
# Cas général : on découpe le tableau en 2 partie que l'on trie
pos = longueur // 2
tab1 = tab[:pos]
lgn1 = len(tab1)
tab1 = tri_fusion(tab1, lgn1)
tab2 = tab[pos:]
lgn2 = len(tab2)
tab2 = tri_fusion(tab2, lgn2)
# Fusion des deux parties
pos1, pos2, pos = 0, 0, 0 # position dans tab1, tab2 et t
while pos1 < lgn1 and pos2 < lgn2:
if tab1[pos1] < tab2[pos2]:
# On met tab1[pos1] dans t
tab[pos] = tab1[pos1]
pos1 += 1
else:
# On met tab2[pos2] dans t
tab[pos] = tab2[pos2]
pos2 += 1
pos += 1
if pos1 == len(tab1):
vidage(tab2, pos2, len(tab2), tab, pos)
else:
vidage(tab1, pos1, len(tab1), tab, pos)
return tab
def tri_bulle(tab, longueur):
"""
Tri bulle\n
On compare les couples d'éléments successifs pour placer systématiquement
le plus grand après le plus petit. Un parcours complet du tableau selon
ce processus nous assure que le plus grand élément est en dernière
position. \nOn réitère alors le processus sur le sous tableau restant.\n
Complexité en O(n**2).
:param tab: tableau à trier
:type tab: array
:param longueur: taille du tableau
:return: tableau trié
:rtype: array
"""
if longueur < 2:
# Moins de 2 éléments : pas besoin de trier
return tab
for index in range(longueur - 1):
for j in range(longueur - 1 - index):
if tab[j] > tab[j + 1]:
# On permute
temp = tab[j]
tab[j] = tab[j + 1]
tab[j + 1] = temp
return tab
def tri_rapide(tab, longueur):
"""
Tri rapide\n
On choisit un élément du tableau au hasard qui sera 'pivot' et on permute
tous les éléments de manière à placer à gauche du pivot les éléments qui
lui sont inférieurs, et à droite ceux qui lui sont supérieurs.\n
On trie alors de la meme manière les deux moitiés de part et d'autre du
pivot.\n
Complexité en O(nlog(n)).
:param tab: tableau à trier
:type tab: array
:param longueur: taille du tableau
:return: tableau trié
:rtype: array
"""
def tri_rapide_rec(tab, i, j):
if i >= j:
# Pas besoin de trier
return tab
pos = i
# On place les éléments plus petits que le pivot (tab[j-1]) au début
for k in range(i, j - 1):
if tab[k] <= tab[j - 1]:
tab[k], tab[pos] = tab[pos], tab[k]
pos += 1
# On remet le pivot après les éléments plus petits
tab[j - 1], tab[pos] = tab[pos], tab[j - 1]
# On trie les deux parties
tri_rapide_rec(tab, i, pos - 1)
tri_rapide_rec(tab, pos + 1, j - 1)
return tab
if longueur < 2:
# Moins de 2 éléments : pas besoin de trier
return tab
tab = tri_rapide_rec(tab, 0, longueur)
return tab
if __name__ == '__main__':
import sys
sys.setrecursionlimit(100000)
TAB_LONGUEURS = [10, 1000, 10000]
TAB_METHODS = {0: tri_selection, 1: tri_recursif, 2: tri_insertion, 3: tri_fusion, 4: tri_bulle, 5: tri_rapide}
for longueurT in TAB_LONGUEURS:
t0 = random.sample(range(1, 100000), longueurT)
print("############# LONGUEUR :" + str(longueurT) + " ###########")
for idx in range(6):
start = timeit.default_timer()
TAB_METHODS[idx](t0, longueurT)
stop = timeit.default_timer()
execution_time = stop - start
print(TAB_METHODS[idx].__name__ + " => " + str(execution_time))
\ No newline at end of file
#!/usr/bin/env python
import unittest
import logging
import sys
from tri import *
class TestTri(unittest.TestCase):
"""
Classe de test permettant de valider le bon fonctionnement des fonctions de tri
"""
def setUp(self):
"""
Initialisation d'un tableau random de taille n pour le dernier cas de test
Comparaison possible avec le tableau trié gràce à la fonction sort
"""
n=100
tableau_n= random.sample(range(1,n+1), n)
tableau_n_sorted = tableau_n
tableau_n_sorted.sort()
self.tableau=[[0],[1,2,3],[3,1,0],[1,1,1],[-1,0,1],[1,0,-1],[0.3,0.2,0.1],tableau_n]
self.longueur=[1,3,3,3,3,3,3,n]
self.tableau_res=[[0],[1,2,3],[0,1,3],[1,1,1],[-1,0,1],[-1,0,1],[0.1,0.2,0.3],tableau_n_sorted]
def test_tri_selection(self):
print("tri_selection")
for i in range(len(self.longueur)):
self.assertEqual(tri_selection(self.tableau[i],self.longueur[i]),self.tableau_res[i])
def test_tri_recursif(self):
print("tri_recursif")
for i in range(len(self.longueur)):
self.assertEqual(tri_recursif(self.tableau[i],self.longueur[i]),self.tableau_res[i])
def test_tri_insertion(self):
print("tri_insertion")
for i in range(len(self.longueur)):
self.assertEqual(tri_insertion(self.tableau[i],self.longueur[i]),self.tableau_res[i])
def test_tri_fusion(self):
print("tri_fusion")
for i in range(len(self.longueur)):
self.assertEqual(tri_fusion(self.tableau[i],self.longueur[i]),self.tableau_res[i])
def test_tri_bulle(self):
print("tri_bulle")
for i in range(len(self.longueur)):
self.assertEqual(tri_bulle(self.tableau[i],self.longueur[i]),self.tableau_res[i])
def test_tri_rapide(self):
print("tri_rapide")
for i in range(len(self.longueur)):
self.assertEqual(tri_rapide(self.tableau[i],self.longueur[i]),self.tableau_res[i])
if __name__ == '__main__':
unittest.main()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment