Ajouter Readme.md
This commit is contained in:
		
							
								
								
									
										155
									
								
								Readme.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								Readme.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,155 @@
 | 
				
			|||||||
 | 
					**Exercice 1**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. **`function_1(tableau1, tableau2)`** :  
 | 
				
			||||||
 | 
					   Dans cette fonction, il y a deux boucles imbriquées : la première parcourt tous les éléments de `tableau1` (de taille \(n\)), et pour chaque élément, la deuxième boucle parcourt `tableau2` (de taille \(m\)).  
 | 
				
			||||||
 | 
					   Dans le pire des cas, si aucun élément ne correspond (ou si le `break` n'est jamais atteint), chaque élément de `tableau1` sera comparé à tous les éléments de `tableau2`.  
 | 
				
			||||||
 | 
					   Donc, la complexité de cette fonction est \( O(n \cdot m) \).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. **`function_2(x)`** :  
 | 
				
			||||||
 | 
					   Ici, on a une boucle `while` qui s’exécute \(x\) 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\), donc \( O(x) \).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. **`function_3(x)`** :  
 | 
				
			||||||
 | 
					   Cette fonction contient uniquement des blocs `if` 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 donc \( O(1) \), car c’est constant peu importe la valeur de \(x\).  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Exercice 2**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Pour analyser la complexité de la fonction **`sort_students`**, on décompose chaque étape :
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. **Boucle externe sur les grades** :  
 | 
				
			||||||
 | 
					   La boucle externe parcourt tous les grades des étudiants, soit \( \text{grades\_number} \) itérations.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. **Allocation dynamique des notes** :  
 | 
				
			||||||
 | 
					   L’allocation du tableau `grades` est faite avec `malloc`, qui est supposée avoir une complexité \( O(1) \). Cela n’affecte donc pas significativement la complexité globale.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. **Copie des notes des étudiants** :  
 | 
				
			||||||
 | 
					   Dans la boucle interne :
 | 
				
			||||||
 | 
					   ```c
 | 
				
			||||||
 | 
					   for(j = 0; j < students_number; j++) {
 | 
				
			||||||
 | 
					       grades[j] = students_array[j][i];
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					   ```
 | 
				
			||||||
 | 
					   on copie les notes des \( \text{students\_number} \) étudiants, ce qui prend \( O(\text{students\_number}) \) par itération de la boucle externe.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					4. **Tri des notes avec `bubblesort`** :  
 | 
				
			||||||
 | 
					   La fonction `bubblesort` trie un tableau de taille \( \text{students\_number} \), avec une complexité \( O(\text{students\_number}^2) \).  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					5. **Trouver le rang de chaque étudiant** :  
 | 
				
			||||||
 | 
					   Ensuite, dans cette boucle interne :
 | 
				
			||||||
 | 
					   ```c
 | 
				
			||||||
 | 
					   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 de \( O(\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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					6. **Libération de mémoire** :  
 | 
				
			||||||
 | 
					   Enfin, la mémoire allouée pour `grades` est libérée avec `free`, ce qui est une opération \( O(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é**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Pour trier un tableau à \( N \)-dimensions avec \( M \) valeurs par dimension, voici l'algo. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Étapes de l’algorithme :
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Si on est au niveau d’un tableau 1D (dimension la plus basse), on le trie directement.
 | 
				
			||||||
 | 
					2. Sinon :
 | 
				
			||||||
 | 
					   - Trier chaque sous-dimension récursivement.
 | 
				
			||||||
 | 
					   - Calculer la somme des valeurs de chaque sous-dimension.
 | 
				
			||||||
 | 
					   - Trier les sous-dimensions en fonction de leurs sommes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### **Implémentation en Python**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Voici l’algorithme en code :
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```python
 | 
				
			||||||
 | 
					def recursive_sort(T):
 | 
				
			||||||
 | 
					    # Si c'est un tableau 1D, on le trie directement
 | 
				
			||||||
 | 
					    if not isinstance(T[0], list):
 | 
				
			||||||
 | 
					        return sorted(T)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Sinon, on trie chaque sous-dimension récursivement
 | 
				
			||||||
 | 
					    for i in range(len(T)):
 | 
				
			||||||
 | 
					        T[i] = recursive_sort(T[i])
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Puis on trie le tableau actuel selon la somme des sous-dimensions
 | 
				
			||||||
 | 
					    T.sort(key=lambda x: sum(sum(val) if isinstance(val, list) else val for val in x))
 | 
				
			||||||
 | 
					    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**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Pour le tableau donné :  
 | 
				
			||||||
 | 
					\[ [ [0, 3, 2], [9, 4, 5], [4, 1, 3] ] \]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. **Trier chaque ligne individuellement** :  
 | 
				
			||||||
 | 
					   \[
 | 
				
			||||||
 | 
					   [ [0, 2, 3], [4, 5, 9], [1, 3, 4] ]
 | 
				
			||||||
 | 
					   \]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. **Calculer la somme des valeurs pour chaque ligne** :  
 | 
				
			||||||
 | 
					   - Première ligne : \( 0 + 2 + 3 = 5 \)  
 | 
				
			||||||
 | 
					   - Deuxième ligne : \( 4 + 5 + 9 = 18 \)  
 | 
				
			||||||
 | 
					   - Troisième ligne : \( 1 + 3 + 4 = 8 \)  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. **Trier les lignes en fonction de leurs sommes** :  
 | 
				
			||||||
 | 
					   \[
 | 
				
			||||||
 | 
					   [ [0, 2, 3], [1, 3, 4], [4, 5, 9] ]
 | 
				
			||||||
 | 
					   \]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### **Complexité de l’algorithme**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Analyse :
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. **Pour la dimension la plus basse (1D)** :  
 | 
				
			||||||
 | 
					   - Trier \( M \) éléments coûte \( O(M \log M) \).  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. **Pour les dimensions supérieures (\( N > 1 \))** :  
 | 
				
			||||||
 | 
					   - Chaque dimension contient \( M^{N-1} \) sous-tableaux.
 | 
				
			||||||
 | 
					   - Trier ces sous-tableaux coûte \( O(M^{N-1} \log M^{N-1}) \).
 | 
				
			||||||
 | 
					   - Calculer les sommes pour ces sous-tableaux prend \( O(M^N) \).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. **Récursivité sur \( N \) dimensions** :  
 | 
				
			||||||
 | 
					   - La complexité totale est donnée par la somme :  
 | 
				
			||||||
 | 
					     \[
 | 
				
			||||||
 | 
					     T(N, M) = O(M^N \log M + M^{N-1} \log M^{N-1} + \dots + M \log M)
 | 
				
			||||||
 | 
					     \]
 | 
				
			||||||
 | 
					   - La partie dominante est celle de la dimension principale :  
 | 
				
			||||||
 | 
					     \[
 | 
				
			||||||
 | 
					     T(N, M) = O(M^N \log M)
 | 
				
			||||||
 | 
					     \]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### **Conclusion**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- La complexité globale est **\( O(M^N \log M) \)**.  
 | 
				
			||||||
		Reference in New Issue
	
	Block a user