forked from menault/2026_TD3_DEV51_Qualite_Algo
opti tri_par_montant
This commit is contained in:
@@ -71,15 +71,48 @@ Transaction *generer_transactions(int n)
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
/* F1 : trie les transactions par montant croissant, puis par id */
|
||||
void trier_par_montant(Transaction *t, int n)
|
||||
{
|
||||
for (int i = 0; i < n - 1; i++) {
|
||||
for (int j = 0; j < n - 1 - i; j++) {
|
||||
if (t[j].montant > t[j + 1].montant ||
|
||||
(t[j].montant == t[j + 1].montant && t[j].id > t[j + 1].id)) {
|
||||
Transaction tmp = t[j];
|
||||
t[j] = t[j + 1];
|
||||
t[j + 1] = tmp;
|
||||
static void fusionner(Transaction *t, int debut, int milieu, int fin) {
|
||||
int n1 = milieu - debut + 1;
|
||||
int n2 = fin - milieu;
|
||||
|
||||
Transaction *gauche = malloc(n1 * sizeof(Transaction));
|
||||
Transaction *droite = malloc(n2 * sizeof(Transaction));
|
||||
|
||||
for (int i = 0; i < n1; i++)
|
||||
gauche[i] = t[debut + i];
|
||||
for (int j = 0; j < n2; j++)
|
||||
droite[j] = t[milieu + 1 + j];
|
||||
|
||||
int i = 0, j = 0, k = debut;
|
||||
|
||||
while (i < n1 && j < n2) {
|
||||
if (gauche[i].montant < droite[j].montant ||
|
||||
(gauche[i].montant == droite[j].montant && gauche[i].id <= droite[j].id)) {
|
||||
t[k++] = gauche[i++];
|
||||
} else {
|
||||
t[k++] = droite[j++];
|
||||
}
|
||||
}
|
||||
|
||||
while (i < n1)
|
||||
t[k++] = gauche[i++];
|
||||
while (j < n2)
|
||||
t[k++] = droite[j++];
|
||||
|
||||
free(gauche);
|
||||
free(droite);
|
||||
}
|
||||
|
||||
void trier_par_montant(Transaction *t, int n) {
|
||||
if (n <= 1) return;
|
||||
|
||||
for (int taille = 1; taille < n; taille *= 2) {
|
||||
for (int debut = 0; debut < n - 1; debut += 2 * taille) {
|
||||
int milieu = debut + taille - 1;
|
||||
int fin = (debut + 2 * taille - 1 < n - 1) ? (debut + 2 * taille - 1) : (n - 1);
|
||||
|
||||
if (milieu < fin) {
|
||||
fusionner(t, debut, milieu, fin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+43
-11
@@ -1,13 +1,45 @@
|
||||
complexités Algorithmique :
|
||||
# Compte rendu — TD3 Complexité algorithmique (R5.A.04)
|
||||
|
||||
F1 : O(n^2)
|
||||
F2 : O(n^2)
|
||||
F3 : O(n*c)
|
||||
F4 : O(n*J)
|
||||
F5 : O(J^3)
|
||||
F6 : O(n)
|
||||
F7: O(n^2)
|
||||
F8 : O(2^S)
|
||||
F9 : M=14
|
||||
F10 : O(L)
|
||||
## 1. Complexités algorithmiques
|
||||
|
||||
| Fonction | Rôle | Avant | Après |
|
||||
|---|---|---|---|
|
||||
| F1 | `trier_par_montant` — tri par montant puis par id | O(n²) | **O(n log n)** (tri fusion) |
|
||||
| F2 | `nb_clients_distincts` | O(n²) | |
|
||||
| F3 | `total_par_client` | O(n·c) | |
|
||||
| F4 | `total_par_jour` | O(n·J) | |
|
||||
| F5 | `meilleure_periode` | O(J³) | |
|
||||
| F6 | `rechercher_par_id` | O(n) | |
|
||||
| F7 | `nb_paires_opposees` | O(n²) | |
|
||||
| F8 | `nb_facons_rendre` | O(2^S) | |
|
||||
| F9 | `categorie` | M = 14 | |
|
||||
| F10 | `ajouter_ligne` | O(L) | |
|
||||
|
||||
## 2. Profil gprof initial
|
||||
|
||||
Programme d'origine compilé avec `gcc -O0 -g -pg`, temps total mesuré : **6,83 s**.
|
||||
|
||||

|
||||
|
||||
`trier_par_montant` représente à elle seule **48 %** du temps (3,28 s) : c'est la première fonction à optimiser.
|
||||
|
||||
## 3. Optimisations
|
||||
|
||||
### 3.1 F1 — `trier_par_montant` : tri à bulles → tri fusion
|
||||
|
||||
**Avant :** tri à bulles, deux boucles imbriquées qui comparent et échangent les éléments voisins → O(n²).
|
||||
|
||||
**Après :** tri fusion itératif (ascendant). On fusionne des sous-tableaux triés de taille 1, 2, 4, 8… jusqu'à couvrir tout le tableau. La fonction `fusionner` copie les deux moitiés dans des tableaux temporaires puis les recombine dans l'ordre → O(n log n).
|
||||
|
||||
L'ordre de tri est conservé (montant croissant, puis id croissant en cas d'égalité), donc l'empreinte reste `ff68d260a7a58441`.
|
||||
|
||||
**Profil gprof après modification :**
|
||||
|
||||

|
||||
|
||||
| | Avant | Après |
|
||||
|---|---|---|
|
||||
| Temps de `trier_par_montant` | 3,28 s | 0,01 s (via `fusionner`) |
|
||||
| Temps total du programme | 6,83 s | 3,06 s |
|
||||
|
||||
Le tri passe de 48 % du temps à un coût négligeable ; le temps total est divisé par plus de 2. Les fonctions les plus coûteuses sont maintenant `nb_facons_rendre` (30 %), `nb_paires_opposees` (24 %) et `rechercher_par_id` (22 %).
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
+61
-60
@@ -2,82 +2,83 @@ Flat profile:
|
||||
|
||||
Each sample counts as 0.01 seconds.
|
||||
% cumulative self self total
|
||||
time seconds seconds calls s/call s/call name
|
||||
48.02 3.28 3.28 1 3.28 3.28 trier_par_montant
|
||||
12.59 4.14 0.86 30000 0.00 0.00 rechercher_par_id
|
||||
11.71 4.94 0.80 1 0.80 0.80 nb_paires_opposees
|
||||
9.96 5.62 0.68 1 0.68 0.68 nb_facons_rendre
|
||||
6.30 6.05 0.43 6017 0.00 0.00 longueur
|
||||
4.69 6.37 0.32 1 0.32 0.32 meilleure_periode
|
||||
2.20 6.52 0.15 _init
|
||||
1.76 6.64 0.12 1 0.12 0.12 total_par_client
|
||||
1.46 6.74 0.10 1 0.10 0.10 nb_clients_distincts
|
||||
0.88 6.80 0.06 1 0.06 0.06 total_par_jour
|
||||
0.44 6.83 0.03 30000 0.00 0.00 categorie
|
||||
0.00 6.83 0.00 149998 0.00 0.00 alea
|
||||
0.00 6.83 0.00 6017 0.00 0.00 ajouter_ligne
|
||||
0.00 6.83 0.00 1 0.00 0.00 empreinte
|
||||
0.00 6.83 0.00 1 0.00 0.00 generer_transactions
|
||||
time seconds seconds calls ms/call ms/call name
|
||||
30.39 0.93 0.93 1 930.00 930.00 nb_facons_rendre
|
||||
23.86 1.66 0.73 1 730.00 730.00 nb_paires_opposees
|
||||
21.57 2.32 0.66 30000 0.02 0.02 rechercher_par_id
|
||||
8.50 2.58 0.26 6017 0.04 0.04 longueur
|
||||
7.52 2.81 0.23 1 230.00 230.00 meilleure_periode
|
||||
3.59 2.92 0.11 1 110.00 110.00 nb_clients_distincts
|
||||
2.61 3.00 0.08 1 80.00 80.00 total_par_client
|
||||
1.31 3.04 0.04 1 40.00 40.00 total_par_jour
|
||||
0.33 3.05 0.01 30000 0.00 0.00 categorie
|
||||
0.33 3.06 0.01 29999 0.00 0.00 fusionner
|
||||
0.00 3.06 0.00 149998 0.00 0.00 alea
|
||||
0.00 3.06 0.00 6017 0.00 0.04 ajouter_ligne
|
||||
0.00 3.06 0.00 1 0.00 0.00 empreinte
|
||||
0.00 3.06 0.00 1 0.00 0.00 generer_transactions
|
||||
0.00 3.06 0.00 1 0.00 10.00 trier_par_montant
|
||||
|
||||
Call graph
|
||||
|
||||
|
||||
granularity: each sample hit covers 4 byte(s) for 0.15% of 6.83 seconds
|
||||
granularity: each sample hit covers 4 byte(s) for 0.33% of 3.06 seconds
|
||||
|
||||
index % time self children called name
|
||||
<spontaneous>
|
||||
[1] 97.8 0.00 6.68 main [1]
|
||||
3.28 0.00 1/1 trier_par_montant [2]
|
||||
0.86 0.00 30000/30000 rechercher_par_id [3]
|
||||
0.80 0.00 1/1 nb_paires_opposees [4]
|
||||
0.68 0.00 1/1 nb_facons_rendre [5]
|
||||
0.00 0.43 6017/6017 ajouter_ligne [6]
|
||||
0.32 0.00 1/1 meilleure_periode [8]
|
||||
0.12 0.00 1/1 total_par_client [10]
|
||||
0.10 0.00 1/1 nb_clients_distincts [11]
|
||||
0.06 0.00 1/1 total_par_jour [12]
|
||||
0.03 0.00 30000/30000 categorie [13]
|
||||
[1] 100.0 0.00 3.06 main [1]
|
||||
0.93 0.00 1/1 nb_facons_rendre [2]
|
||||
0.73 0.00 1/1 nb_paires_opposees [3]
|
||||
0.66 0.00 30000/30000 rechercher_par_id [4]
|
||||
0.00 0.26 6017/6017 ajouter_ligne [5]
|
||||
0.23 0.00 1/1 meilleure_periode [7]
|
||||
0.11 0.00 1/1 nb_clients_distincts [8]
|
||||
0.08 0.00 1/1 total_par_client [9]
|
||||
0.04 0.00 1/1 total_par_jour [10]
|
||||
0.01 0.00 30000/30000 categorie [11]
|
||||
0.00 0.01 1/1 trier_par_montant [13]
|
||||
0.00 0.00 1/1 generer_transactions [16]
|
||||
0.00 0.00 1/1 empreinte [15]
|
||||
-----------------------------------------------
|
||||
3.28 0.00 1/1 main [1]
|
||||
[2] 48.0 3.28 0.00 1 trier_par_montant [2]
|
||||
266723738 nb_facons_rendre [2]
|
||||
0.93 0.00 1/1 main [1]
|
||||
[2] 30.4 0.93 0.00 1+266723738 nb_facons_rendre [2]
|
||||
266723738 nb_facons_rendre [2]
|
||||
-----------------------------------------------
|
||||
0.86 0.00 30000/30000 main [1]
|
||||
[3] 12.6 0.86 0.00 30000 rechercher_par_id [3]
|
||||
0.73 0.00 1/1 main [1]
|
||||
[3] 23.9 0.73 0.00 1 nb_paires_opposees [3]
|
||||
-----------------------------------------------
|
||||
0.80 0.00 1/1 main [1]
|
||||
[4] 11.7 0.80 0.00 1 nb_paires_opposees [4]
|
||||
0.66 0.00 30000/30000 main [1]
|
||||
[4] 21.6 0.66 0.00 30000 rechercher_par_id [4]
|
||||
-----------------------------------------------
|
||||
266723738 nb_facons_rendre [5]
|
||||
0.68 0.00 1/1 main [1]
|
||||
[5] 10.0 0.68 0.00 1+266723738 nb_facons_rendre [5]
|
||||
266723738 nb_facons_rendre [5]
|
||||
0.00 0.26 6017/6017 main [1]
|
||||
[5] 8.5 0.00 0.26 6017 ajouter_ligne [5]
|
||||
0.26 0.00 6017/6017 longueur [6]
|
||||
-----------------------------------------------
|
||||
0.00 0.43 6017/6017 main [1]
|
||||
[6] 6.3 0.00 0.43 6017 ajouter_ligne [6]
|
||||
0.43 0.00 6017/6017 longueur [7]
|
||||
0.26 0.00 6017/6017 ajouter_ligne [5]
|
||||
[6] 8.5 0.26 0.00 6017 longueur [6]
|
||||
-----------------------------------------------
|
||||
0.43 0.00 6017/6017 ajouter_ligne [6]
|
||||
[7] 6.3 0.43 0.00 6017 longueur [7]
|
||||
0.23 0.00 1/1 main [1]
|
||||
[7] 7.5 0.23 0.00 1 meilleure_periode [7]
|
||||
-----------------------------------------------
|
||||
0.32 0.00 1/1 main [1]
|
||||
[8] 4.7 0.32 0.00 1 meilleure_periode [8]
|
||||
0.11 0.00 1/1 main [1]
|
||||
[8] 3.6 0.11 0.00 1 nb_clients_distincts [8]
|
||||
-----------------------------------------------
|
||||
<spontaneous>
|
||||
[9] 2.2 0.15 0.00 _init [9]
|
||||
0.08 0.00 1/1 main [1]
|
||||
[9] 2.6 0.08 0.00 1 total_par_client [9]
|
||||
-----------------------------------------------
|
||||
0.12 0.00 1/1 main [1]
|
||||
[10] 1.8 0.12 0.00 1 total_par_client [10]
|
||||
0.04 0.00 1/1 main [1]
|
||||
[10] 1.3 0.04 0.00 1 total_par_jour [10]
|
||||
-----------------------------------------------
|
||||
0.10 0.00 1/1 main [1]
|
||||
[11] 1.5 0.10 0.00 1 nb_clients_distincts [11]
|
||||
0.01 0.00 30000/30000 main [1]
|
||||
[11] 0.3 0.01 0.00 30000 categorie [11]
|
||||
-----------------------------------------------
|
||||
0.06 0.00 1/1 main [1]
|
||||
[12] 0.9 0.06 0.00 1 total_par_jour [12]
|
||||
0.01 0.00 29999/29999 trier_par_montant [13]
|
||||
[12] 0.3 0.01 0.00 29999 fusionner [12]
|
||||
-----------------------------------------------
|
||||
0.03 0.00 30000/30000 main [1]
|
||||
[13] 0.4 0.03 0.00 30000 categorie [13]
|
||||
0.00 0.01 1/1 main [1]
|
||||
[13] 0.3 0.00 0.01 1 trier_par_montant [13]
|
||||
0.01 0.00 29999/29999 fusionner [12]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 149998/149998 generer_transactions [16]
|
||||
[14] 0.0 0.00 0.00 149998 alea [14]
|
||||
@@ -92,8 +93,8 @@ index % time self children called name
|
||||
|
||||
Index by function name
|
||||
|
||||
[9] _init [16] generer_transactions [4] nb_paires_opposees
|
||||
[6] ajouter_ligne [7] longueur [3] rechercher_par_id
|
||||
[14] alea [8] meilleure_periode [10] total_par_client
|
||||
[13] categorie [11] nb_clients_distincts [12] total_par_jour
|
||||
[15] empreinte [5] nb_facons_rendre [2] trier_par_montant
|
||||
[5] ajouter_ligne [16] generer_transactions [3] nb_paires_opposees
|
||||
[14] alea [6] longueur [4] rechercher_par_id
|
||||
[11] categorie [7] meilleure_periode [9] total_par_client
|
||||
[15] empreinte [8] nb_clients_distincts [10] total_par_jour
|
||||
[12] fusionner (banque.c) [2] nb_facons_rendre [13] trier_par_montant
|
||||
|
||||
Reference in New Issue
Block a user