Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Docker-in-Docker (DinD) capabilities of public runners deactivated.
More info
Open sidebar
Cyril L'Orphelin
anf-qualite_logicielle
Commits
735e5c6b
Commit
735e5c6b
authored
Oct 20, 2021
by
Cyril L'Orphelin
Browse files
TP4 : restructuration du TP
parent
31e4544d
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
322 additions
and
0 deletions
+322
-0
TP4/solutions/__pycache__/tri.cpython-38.pyc
TP4/solutions/__pycache__/tri.cpython-38.pyc
+0
-0
TP4/solutions/__pycache__/tri_test.cpython-38.pyc
TP4/solutions/__pycache__/tri_test.cpython-38.pyc
+0
-0
TP4/solutions/tri.py
TP4/solutions/tri.py
+260
-0
TP4/solutions/tri_test.py
TP4/solutions/tri_test.py
+62
-0
No files found.
TP4/solutions/__pycache__/tri.cpython-38.pyc
0 → 100644
View file @
735e5c6b
File added
TP4/solutions/__pycache__/tri_test.cpython-38.pyc
0 → 100644
View file @
735e5c6b
File added
TP4/solutions/tri.py
0 → 100644
View file @
735e5c6b
# -*- 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.
\n
On 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
TP4/solutions/tri_test.py
0 → 100644
View file @
735e5c6b
#!/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
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment