Readme.md | ||
TD4 - DEV5.1.pdf |
Exercice 1
-
function_1(tableau1, tableau2)
:
Dans cette fonction, il y a deux boucles imbriquées : la première parcourt tous les éléments detableau1
(de taillen
), et pour chaque élément, la deuxième boucle parcourttableau2
(de taillem
).
Dans le pire des cas, si aucun élément ne correspond (ou si lebreak
n'est jamais atteint), chaque élément detableau1
sera comparé à tous les éléments detableau2
.
Donc, la complexité de cette fonction estO(n \cdot m)
. -
function_2(x)
:
Ici, on a une bouclewhile
qui s’exécutex
fois. À chaque itération, on effectue une addition et une décrémentation, qui prennent toutes les deux un temps constant.
Du coup, la complexité est proportionnelle àx
, doncO(x)
. -
function_3(x)
:
Cette fonction contient uniquement des blocsif
indépendants, qui s’exécutent chacun au maximum une seule fois. Il n’y a pas de boucle, donc chaque opération est constante.
La complexité est doncO(1)
, car c’est constant peu importe la valeur dex
.
Exercice 2
Pour analyser la complexité de la fonction sort_students
, on décompose chaque étape :
-
Boucle externe sur les grades :
La boucle externe parcourt tous les grades des étudiants, soit\text{grades\_number}
itérations. -
Allocation dynamique des notes :
L’allocation du tableaugrades
est faite avecmalloc
, qui est supposée avoir une complexitéO(1)
. Cela n’affecte donc pas significativement la complexité globale. -
Copie des notes des étudiants :
Dans la boucle interne :for(j = 0; j < students_number; j++) { grades[j] = students_array[j][i]; }
on copie les notes des
\text{students\_number}
étudiants, ce qui prendO(\text{students\_number})
par itération de la boucle externe. -
Tri des notes avec
bubblesort
:
La fonctionbubblesort
trie un tableau de taille\text{students\_number}
, avec une complexitéO(\text{students\_number}^2)
. -
Trouver le rang de chaque étudiant :
Ensuite, dans cette boucle interne :for(j = 0; j < students_number; j++) { students_rank[j][i] = find_rank_student(students_array[j][i], grades, students_number); }
on appelle
find_rank_student
pour chaque étudiant. Cette fonction effectue :- Un tri par bulles
O(\text{students\_number}^2)
, - Une recherche pour trouver le rang, qui prend
O(\text{students\_number})
.
Donc, chaque appel à
find_rank_student
a une complexité totale deO(\text{students\_number}^2)
, et cette fonction est appelée\text{students\_number}
fois par itération de la boucle externe. Cela donne une complexitéO(\text{students\_number}^3)
par itération de la boucle externe. - Un tri par bulles
-
Libération de mémoire :
Enfin, la mémoire allouée pourgrades
est libérée avecfree
, ce qui est une opérationO(1)
.
Complexité totale :
La boucle externe s’exécute \text{grades\_number}
fois, et la partie la plus coûteuse de la boucle interne est O(\text{students\_number}^3)
. La complexité globale de la fonction est donc :
O(\text{grades\_number} \cdot \text{students\_number}^3)
Conclusion :
La fonction sort_students
a une complexité algorithmique de
O(\text{grades\_number} \cdot \text{students\_number}^3)
Exercice 3
Algorithme proposé
-
Tri des sous-dimensions :
- Si on est sur un tableau 1D (le plus bas niveau), on le trie avec un tri par insertion.
-
Calcul des sommes des sous-dimensions :
- Pour chaque sous-tableau, on calcule la somme des valeurs pour s’en servir comme critère de tri.
-
Tri des sous-dimensions par leurs sommes :
- On trie les sous-dimensions avec un tri par insertion basé sur les sommes calculées.
-
Répétition pour les autres dimensions :
- On applique ces étapes de façon récursive à chaque niveau du tableau.
Implémentation
Voici l'algorithme en Python :
# Fonction pour trier un tableau 1D avec un tri par insertion
def insertion_sort(arr):
for i in range(1, len(arr)):
key = arr[i]
j = i - 1
# Déplacement des éléments plus grands que key
while j >= 0 and arr[j] > key:
arr[j + 1] = arr[j]
j -= 1
arr[j + 1] = key
# Fonction pour trier un tableau multidimensionnel récursivement
def recursive_sort(T):
# Si c'est un tableau 1D, on le trie
if not isinstance(T[0], list):
insertion_sort(T)
return T
# Trier chaque sous-dimension
for i in range(len(T)):
T[i] = recursive_sort(T[i])
# Calculer les sommes des sous-dimensions
sums = [sum(sum(val) if isinstance(val, list) else val for val in sublist) for sublist in T]
# Trier les sous-dimensions en fonction de leurs sommes
for i in range(1, len(T)):
key_sum = sums[i]
key_sublist = T[i]
j = i - 1
while j >= 0 and sums[j] > key_sum:
sums[j + 1] = sums[j]
T[j + 1] = T[j]
j -= 1
sums[j + 1] = key_sum
T[j + 1] = key_sublist
return T
# Exemple avec un tableau 2D
tableau = [[0, 3, 2], [9, 4, 5], [4, 1, 3]]
resultat = recursive_sort(tableau)
print(resultat) # Résultat attendu : [[0, 2, 3], [1, 3, 4], [4, 5, 9]]
Exemple d’exécution
Prenons le tableau suivant :
[ [0, 3, 2], [9, 4, 5], [4, 1, 3] ]
-
Trier chaque ligne :
- Première ligne :
[0, 3, 2] \rightarrow [0, 2, 3]
- Deuxième ligne :
[9, 4, 5] \rightarrow [4, 5, 9]
- Troisième ligne :
[4, 1, 3] \rightarrow [1, 3, 4]
[ [0, 2, 3], [4, 5, 9], [1, 3, 4] ]
- Première ligne :
-
Calculer les sommes :
[0, 2, 3] \rightarrow 5
[4, 5, 9] \rightarrow 18
[1, 3, 4] \rightarrow 8
-
Trier les lignes en fonction des sommes :
[ [0, 2, 3], [1, 3, 4], [4, 5, 9] ]
Complexité
Analyse :
-
Tri des tableaux 1D :
- Pour
M
éléments, le tri par insertion a une complexité deO(M^2)
.
- Pour
-
Tri des sous-tableaux (dimensions
N > 1
) :- Chaque sous-tableau contient
M^{N-1}
éléments. Trier ces sous-tableaux coûteO(M^{N-1} \cdot M^{N-1}) = O(M^{2(N-1)})
.
- Chaque sous-tableau contient
-
Calcul des sommes :
- Calculer les sommes pour
M^{N-1}
sous-tableaux coûteO(M^N)
.
- Calculer les sommes pour
-
Complexité totale :
- L'algorithme s’applique de façon récursive sur
N
dimensions. La partie dominante vient du tri des sous-tableaux les plus grands :T(N, M) = O(M^{2N-2})
- L'algorithme s’applique de façon récursive sur
Conclusion
-
- La complexité globale est
[ O(M^{2N-2})
- La complexité globale est