rapport début

This commit is contained in:
2026-10-21 11:13:21 +02:00
parent e337ed5236
commit 2bd16d1b2c
6 changed files with 6321 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
# Compte rendu — TD 3 : complexité algorithmique
Nathan COUCHOT et Lucas POT
## 1. Mesurer le programme
```bash
gcc -O2 banque.c -o banque
time ./banque
```
La version initiale s'exécute en environ **2,26 s**.
| Mesure initiale | Résultat |
| --- | ---: |
| Temps réel (`real`) | 2,26 s |
| Temps CPU utilisateur (`user`) | 2,23 s |
| Temps CPU système (`sys`) | 0,00 s |
| Empreinte | `ff68d260a7a58441` |
L'empreinte attendue est **`ff68d260a7a58441`**.
## 2. Profiler et analyser le programme initial
```bash
gcc -O0 -g -pg banque.c -o banque_pg
./banque_pg
gprof ./banque_pg gmon.out > profil_avant.txt
```
Le temps réel mesuré avec l'instrumentation est **8,35 s**, contre **2,26 s** sans `-pg`. Cette différence vient en partie du coût ajouté par le comptage des appels. Le profil complet est fourni dans profil_avant.txt.
| Fonction | Part du temps propre | Temps propre | Appels |
| --- | ---: | ---: | ---: |
| `trier_par_montant` | 49,43 % | 3,02 s | 1 |
| `rechercher_par_id` | 13,42 % | 0,82 s | 30 000 |
| `nb_paires_opposees` | 11,95 % | 0,73 s | 1 |
| `nb_facons_rendre` | 8,27 % | 0,51 s | 1 appel depuis `main` |
| `longueur` | 6,87 % | 0,42 s | 6 017 |
| `meilleure_periode` | 4,91 % | 0,30 s | 1 |
| `total_par_client` | 1,80 % | 0,11 s | 1 |
| `nb_clients_distincts` | 1,64 % | 0,10 s | 1 |
| `total_par_jour` | 0,82 % | 0,05 s | 1 |
Le tri à bulles est le principal point chaud du profil. `rechercher_par_id` est appelée 30 000 fois et parcourt le tableau à chaque recherche. `ajouter_ligne` appelle `longueur` pour retrouver la fin du rapport ; comme le rapport grandit à chaque ajout, ces recherches répétées reparcourent une quantité croissante de caractères.
Le graphe d'appels permet aussi de voir le coût récursif de `nb_facons_rendre`. Le profil plat ne montre qu'un appel depuis `main`, mais cet appel entraîne de nombreux appels récursifs. Le temps propre observé ne suffit donc pas à lui seul pour expliquer le coût total.
Les fonctions les plus coûteuses n'ont pas nécessairement les complexités les plus élevées. Le tri traite 30 000 transactions, tandis que `meilleure_periode` traite 1 000 jours. Le temps mesuré dépend à la fois de la complexité et de la taille effective des données.
## 3. Complexités algorithmiques et cyclomatiques
On note **n** le nombre de transactions, **C** le nombre de clients, **J** le nombre de jours, **Q** le nombre de requêtes, **S** la somme à rendre, **k** le nombre de pièces et **L** la longueur finale du rapport. Les paramètres sont considérés variables pour l'analyse, même si le programme utilise des constantes.
| Fonction | Calcule | Actuelle | Objectif |
| --- | --- | --- | --- |
| F1 `trier_par_montant` | tri des transactions | O(n²) | O(n log n) |
| F2 `nb_clients_distincts` | clients différents | O(n²) | O(n + C) |
| F3 `total_par_client` | solde par client | O(n * c) | O(n + C) |
| F4 `total_par_jour` | solde par jour | O(n * J) | O(n + J) |
| F5 `meilleure_periode` | période la plus rentable | O(J³) | O(J) |
| F6 `rechercher_par_id` | recherche par identifiant | O(n) | O(1) par requête |
| F7 `nb_paires_opposees` | paires a + b = 0 | O(n²) | O(n log n) |
| F8 `nb_facons_rendre` | rendu de monnaie | O(S^n) | O(S × k) |
| F9 `categorie` | catégorie d'une transaction | M = 14 | M ≤ 10 |
| F10 `ajouter_ligne` | construction du rapport | O(n) | O(L) au total |
### Complexité cyclomatique des fonctions F1 à F10
On calcule **M = nombre de décisions + 1**.
| Fonction | Décisions | Calcul de M |
| --- | --- | ---: |
| F1 `trier_par_montant` | 2 `for` + 1 `if` + 1 `||` + 1 `&&` | 5 + 1 = **6** |
| F2 `nb_clients_distincts` | 2 `for` + 2 `if` | 4 + 1 = **5** |
| F3 `total_par_client` | 2 `for` + 1 `if` | 3 + 1 = **4** |
| F4 `total_par_jour` | 2 `for` + 1 `if` | 3 + 1 = **4** |
| F5 `meilleure_periode` | 3 `for` + 1 `if` | 4 + 1 = **5** |
| F6 `rechercher_par_id` | 1 `for` + 1 `if` | 2 + 1 = **3** |
| F7 `nb_paires_opposees` | 2 `for` + 1 `if` | 3 + 1 = **4** |
| F8 `nb_facons_rendre` | 2 `if` + 1 `||` | 3 + 1 = **4** |
| F9 `categorie` | 11 `if`/`else if` + 1 `||` + 1 `&&` | 13 + 1 = **14** |
| F10 `ajouter_ligne` | 1 `while` | 1 + 1 = **2** |