This commit is contained in:
rabot
2026-10-21 11:05:36 +02:00
parent e337ed5236
commit 3cdb37276c
13 changed files with 12549 additions and 0 deletions
+234
View File
@@ -0,0 +1,234 @@
# Compte rendu du TD de complexité algorithmique
Ce compte rendu traite les trois étapes du palier 1 du TD
(page 68 de `R5A04_Algorithmique_MM.pdf`) : mesurer la version initiale,
la profiler, puis calculer les complexités algorithmiques et cyclomatiques.
Les mesures ont été réalisées le 21 octobre 2026 sur Linux x86_64, avec
GCC 16.2.1 et GNU gprof 2.47. Le fichier `banque.c` est dans sa version initiale.
Les données sont reproductibles grâce à la graine fixe du générateur.
| Paramètre | Valeur |
|---|---:|
| Transactions, `n` | 30 000 |
| Clients, `C` | 2 000 |
| Jours, `J` | 1 000 |
| Requêtes par identifiant, `Q` | 30 000 |
| Somme à rendre, `S` | 400 centimes |
| Types de pièces, `k` | 8 |
## 1. Mesurer la version initiale
Le Makefile compile le programme avec
`gcc -std=c11 -Wall -Wextra -Wpedantic -O2 banque.c -o build/banque`.
La compilation s'est terminée sans avertissement. Les commandes utilisées
pour compiler et enregistrer une mesure sont les suivantes, depuis la racine :
```bash
make -B all
(cd build && { time -p ./banque > sortie.txt; } 2> temps_avant.txt)
cat build/sortie.txt build/temps_avant.txt
```
Résultat de l'exécution mesurée :
```text
Clients distincts : 2000
Somme des requêtes : -2624578
Meilleure période : jours 650 à 986 (3548830)
Paires opposées : 5832
Façons de rendre 400 : 1960497
Empreinte : ff68d260a7a58441
real 2.43
user 2.39
sys 0.00
```
Le temps réel est de **2,43 s**. Le temps CPU passé dans le programme est de
2,39 s ; le temps système est arrondi à 0,00 s. Cette mesure porte sur une
exécution et peut varier selon la charge de la machine.
L'empreinte obtenue est bien **`ff68d260a7a58441`**, celle attendue dans le TD.
Le rapport produit contient 6 017 lignes, soit 120 348 octets. Les résultats
sont conservés dans [sortie.txt](build/sortie.txt) et
[temps_avant.txt](build/temps_avant.txt).
## 2. Profiler et comparer aux complexités
Le profil a été généré avec les commandes suivantes :
```bash
make profile
cp build/profil/profil.txt build/profil/profil_avant.txt
```
La cible `profile` utilise une compilation en `-O0 -g -pg`, exécute le programme,
puis lance `gprof -b ./banque gmon.out` dans `build/profil`. Le profil initial
est conservé dans [profil_avant.txt](build/profil/profil_avant.txt).
Cette exécution produit également l'empreinte attendue. Les fichiers
`build/rapport.txt` et `build/profil/rapport.txt` ont été comparés : ils sont
identiques octet par octet.
### Résultats de gprof
Le tableau reprend les temps propres du profil plat : ils correspondent au
temps passé dans chaque fonction, hors fonctions appelées. Les pourcentages
portent sur environ **6,44 s de temps CPU échantillonné**.
| Fonction | Appels | Temps propre (s) | Part du temps |
|---|---:|---:|---:|
| F1 — `trier_par_montant` | 1 | 3,13 | 48,60 % |
| F6 — `rechercher_par_id` | 30 000 | 0,85 | 13,20 % |
| F7 — `nb_paires_opposees` | 1 | 0,76 | 11,80 % |
| F8 — `nb_facons_rendre` | 1 appel initial | 0,66 | 10,17 % |
| `longueur`, appelée par F10 | 6 017 | 0,41 | 6,37 % |
| F5 — `meilleure_periode` | 1 | 0,32 | 4,97 % |
| F2 — `nb_clients_distincts` | 1 | 0,11 | 1,71 % |
| F3 — `total_par_client` | 1 | 0,11 | 1,71 % |
| F4 — `total_par_jour` | 1 | 0,05 | 0,78 % |
| F9 — `categorie` | 30 000 | 0,03 | 0,39 % |
| F10 — `ajouter_ligne` | 6 017 | 0,00 | 0,00 % |
Le graphe d'appels précise que F8 effectue **266 723 738 appels récursifs**,
en plus de l'appel initial. Le compteur du profil plat ne montre que cet
appel initial. Les écarts entre les pourcentages et les temps affichés
s'expliquent par les arrondis ; quelques échantillons sont aussi attribués
à `_init`.
Le temps cumulé de F10, en incluant `longueur`, est d'environ **0,41 s**.
Son temps propre affiché à 0,00 s ne signifie donc pas que la construction
du rapport est gratuite. Plus généralement, une valeur nulle dans ce profil
ne prouve pas l'absence de coût : la période d'échantillonnage est de 0,01 s.
Ces temps ne se comparent pas directement aux 2,43 s de la première étape :
le profil utilise `-O0` et l'instrumentation `-pg`, tandis que la mesure
initiale utilise `-O2`. Le profil décrit le comportement de cette version
instrumentée, pour ces données et sur cette machine.
### Les fonctions les plus coûteuses ont-elles les pires complexités ?
**Non, pas systématiquement.** La complexité décrit la croissance du nombre
d'opérations lorsque la taille des entrées augmente. Le profil mesure le coût
d'une exécution précise. Ce coût dépend aussi des tailles effectivement
utilisées, du nombre d'appels, des données et du travail effectué à chaque
itération.
- **F1 : le tri quadratique domine ici.** Le tri à bulles effectue
`n(n - 1) / 2`, soit **449 985 000 comparaisons de paires voisines**, avec
des échanges de structures lorsque les transactions sont mal ordonnées.
Sa complexité est `O(n²)` et il représente 48,60 % du temps échantillonné.
- **F5 : une complexité cubique ne suffit pas à en faire la fonction la plus
lente.** Ses trois boucles donnent une complexité `O(J³)`, mais elles portent
sur **1 000 jours**, alors que F1 traite 30 000 transactions. F5 effectue
`J(J + 1)(J + 2) / 6`, soit **167 167 000 additions**, et prend environ
0,32 s, contre 3,13 s pour F1. Les variables et les tailles diffèrent :
comparer uniquement les exposants serait trompeur.
- **F6 : le nombre d'appels compte.** Une recherche par identifiant est en
`O(n)` au pire cas, mais `main` l'effectue **30 000 fois**. Le coût de
l'ensemble des recherches est donc `O(Q × n)`, soit `O(n²)` lorsque `Q = n`.
Avec 0,85 s au total, F6 arrive devant F5 malgré sa complexité linéaire
par appel.
- **F7 : une même classe de complexité ne donne pas un même temps.** F7
examine elle aussi **449 985 000 paires**, en `O(n²)`, mais se limite à
additionner deux montants, comparer le résultat à zéro et éventuellement
incrémenter un compteur. Elle prend 0,76 s, environ quatre fois moins que
F1, dont les itérations peuvent déplacer des transactions entières.
- **F8 : les sous-problèmes recalculés multiplient les appels.** Le rendu de
monnaie utilise une récursion sans mémorisation et dépasse 266 millions
d'appels récursifs. Son coût dépend de `S` et de `k`, ici 400 et 8. Malgré
cet arbre d'appels volumineux, son temps de 0,66 s reste inférieur à celui
du tri ; le nombre d'appels ne suffit pas non plus à classer les temps.
- **F10 : il faut tenir compte des fonctions appelées et des appels répétés.**
Chaque ajout parcourt tout le rapport existant avec `longueur`, puis copie
la nouvelle ligne. Pour un préfixe de longueur `p` et une ligne de longueur
`l`, un appel coûte `O(p + l)`. Sur `m` ajouts de lignes de taille bornée,
les parcours successifs coûtent `O(m²)`, soit `O(L²)` dans ce cas, où `L`
est la longueur finale du rapport. Pour le rapport obtenu, les recherches
de fin de chaîne relisent **340 702 496 caractères** de préfixes, ce qui
explique les 0,41 s attribuées à `longueur`.
Pour cette exécution instrumentée, F1, F6 et F7 représentent ensemble
**73,60 %** du temps échantillonné : ce sont les premières pistes
d'optimisation indiquées par le profil.
## 3. Calculer les complexités de F1 à F10
Le tableau reprend l'analyse initiale de `notes.md`, avec la complexité
cyclomatique de chaque fonction. Les complexités temporelles sont données
au pire cas, en faisant varier les tailles des données, même si leurs valeurs
sont fixées par des constantes dans le programme. Les objectifs sont ceux
du tableau de la page 67 du TD ; ils restent à atteindre.
| ID | Fonction | Calcule | Actuelle | M | Objectif |
|:---:|---|---|---|:---:|---|
| F1 | `trier_par_montant` | tri des transactions | `O(n²)` | 6 | `O(n log n)` |
| F2 | `nb_clients_distincts` | clients différents | `O(n²)` | 5 | `O(n + C)` |
| F3 | `total_par_client` | solde par client | `O(n × C)` | 4 | `O(n + C)` |
| F4 | `total_par_jour` | solde par jour | `O(n × J)` | 4 | `O(n + J)` |
| F5 | `meilleure_periode` | période la plus rentable | `O(J³)` | 5 | `O(J)` |
| F6 | `rechercher_par_id` | recherche par identifiant | `O(n)` par requête | 3 | `O(1)` par requête |
| F7 | `nb_paires_opposees` | paires `a + b = 0` | `O(n²)` | 4 | `O(n log n)` |
| F8 | `nb_facons_rendre` | rendu de monnaie | `O(2^(S + k))`, borne générale | 4 | `O(S × k)` |
| F9 | `categorie` | catégorie d'une transaction | `O(1)` | 14 | `M ≤ 10` |
| F10 | `ajouter_ligne` | construction du rapport | `O(p + l)` par ajout ; `O(L²)` au total pour des lignes de taille bornée | 2 | `O(L)` au total |
`n` : transactions ; `C` : clients ; `J` : jours ; `Q` : requêtes ;
`S` : somme à rendre ; `k` : types de pièces ; `L` : longueur finale du
rapport ; `p` : longueur du rapport avant un ajout ; `l` : longueur de la
ligne ajoutée. **F5, F7 et F8** sont signalées comme les plus difficiles
dans le TD.
### Justification des complexités temporelles
- **F1 et F7** : les deux boucles parcourent `n(n - 1) / 2` paires.
Le travail par paire est constant, d'où `O(n²)`.
- **F2** : pour chaque transaction d'indice `i`, la recherche d'un client
déjà rencontré peut parcourir les `i` transactions précédentes.
La somme `0 + 1 + … + (n - 1)` donne la borne `O(n²)`, atteinte si
les clients sont tous différents (`C ≥ n`).
- **F3 et F4** : chaque client, puis chaque jour, provoque un parcours
complet des `n` transactions : respectivement `O(C × n)` et `O(J × n)`.
- **F5** : chaque intervalle de jours est essayé, et sa somme est recalculée
par une troisième boucle. Le nombre d'additions est
`J(J + 1)(J + 2) / 6`, d'où `O(J³)`.
- **F6** : une recherche peut lire les `n` transactions, soit `O(n)`.
Les `Q` recherches de `main` coûtent donc `O(Q × n)` au pire cas.
- **F8** : sans mémorisation, le coût suit la récurrence
`T(S, k) = T(S - pièce[k - 1], k) + T(S, k - 1) + O(1)`.
Chaque appel non terminal engendre deux appels ; chaque branche diminue
`S` ou `k` d'au moins 1. La profondeur est donc au plus `S + k`, ce qui
donne la borne générale `O(2^(S + k))`. Cette borne est large : pour
`k` fixé, on peut affiner en `O(S^k)`. La notation `O(Sⁿ)` des notes
initiales ne convient pas, car `n` désigne les transactions.
- **F9** : le nombre de tests est borné, indépendamment de `n`, d'où `O(1)`.
L'objectif porte ici sur la complexité cyclomatique, pas sur le temps.
- **F10** : `longueur` lit les `p` caractères du rapport, puis la fonction
copie les `l` caractères de la ligne : `O(p + l)` par ajout.
Pour `m` lignes non vides de taille bornée, les préfixes relus ont des
longueurs proportionnelles à `0, 1, …, m - 1` : le coût total est
`O(m²)`, soit `O(L²)` dans ce cas.
### Calcul manuel de la complexité cyclomatique
La convention du cours (pages 31–32) est **`M = nombre de décisions + 1`**.
Chaque `if`, `else if`, `for`, `while`, ainsi que chaque opérateur `&&` ou
`||`, ajoute une décision. `else`, `return` et `break` n'en ajoutent pas.
Les décisions d'une fonction appelée se comptent dans cette fonction.
- **F1** : 2 `for` + 1 `if` + 1 `||` + 1 `&&` = 5 décisions, donc **M = 6**.
- **F2** : 2 `for` + 2 `if` = 4 décisions, donc **M = 5**.
- **F3, F4 et F7** : 2 `for` + 1 `if` = 3 décisions chacune, donc **M = 4**.
- **F5** : 3 `for` + 1 `if` = 4 décisions, donc **M = 5**.
- **F6** : 1 `for` + 1 `if` = 2 décisions, donc **M = 3**.
- **F8** : 2 `if` + 1 `||` = 3 décisions, donc **M = 4**.
- **F9** : 11 `if` ou `else if` + 1 `||` + 1 `&&` = 13 décisions,
donc **M = 14**. C'est la plus grande valeur de F1 à F10.
- **F10** : 1 `while` = 1 décision, donc **M = 2**.
La fonction auxiliaire `longueur` contient elle aussi un `while` et a
**M = 2**, compté séparément.
+57
View File
@@ -0,0 +1,57 @@
CC = gcc
CFLAGS ?= -std=c11 -Wall -Wextra -Wpedantic -O2
CFLAGS_PROFIL ?= -std=c11 -Wall -Wextra -Wpedantic -O0 -g -pg
SOURCE = banque.c
PROGRAMME = build/banque
PROGRAMME_PROFIL = build/profil/banque
EMPREINTE_ATTENDUE = ff68d260a7a58441
NOM ?= $(shell whoami)
.PHONY: all run check bench profile clean help
all: $(PROGRAMME)
$(PROGRAMME): $(SOURCE) Makefile
mkdir -p $(@D)
$(CC) $(CPPFLAGS) $(CFLAGS) $< -o $@ $(LDFLAGS) $(LDLIBS)
run: $(PROGRAMME)
cd build && ./banque
check: $(PROGRAMME)
cd build && ./banque > sortie.txt
@cat build/sortie.txt
@empreinte=$$(awk '/^Empreinte/ {print $$NF}' build/sortie.txt); \
if [ "$$empreinte" != "$(EMPREINTE_ATTENDUE)" ]; then \
printf 'Empreinte incorrecte : %s (attendu %s)\n' "$$empreinte" "$(EMPREINTE_ATTENDUE)" >&2; \
exit 1; \
fi
@printf 'Empreinte correcte.\n'
# Le script impose gcc -O2, vérifie l'empreinte et mesure 5 exécutions.
bench: $(SOURCE) evaluer.sh
mkdir -p build
cd build && bash "$(abspath evaluer.sh)" "$(abspath $(SOURCE))" "$(NOM)"
@printf 'Mesures disponibles dans build/resultats.csv\n'
$(PROGRAMME_PROFIL): $(SOURCE) Makefile
mkdir -p $(@D)
$(CC) $(CPPFLAGS) $(CFLAGS_PROFIL) $< -o $@ $(LDFLAGS) $(LDLIBS)
profile: $(PROGRAMME_PROFIL)
cd build/profil && ./banque
cd build/profil && gprof -b ./banque gmon.out > profil.txt
@printf 'Profil disponible dans build/profil/profil.txt\n'
clean:
rm -rf build
help:
@printf '%s\n' \
'make Compiler banque.c avec -O2' \
'make run Exécuter et produire build/rapport.txt' \
"make check Vérifier l'empreinte attendue" \
'make bench NOM=nom Évaluer les performances (médiane de 5 exécutions)' \
'make profile Générer le profil gprof avec -O0 -g -pg' \
'make clean Supprimer build, y compris les mesures et profils'
Executable
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+99
View File
@@ -0,0 +1,99 @@
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
48.60 3.13 3.13 1 3.13 3.13 trier_par_montant
13.20 3.98 0.85 30000 0.00 0.00 rechercher_par_id
11.80 4.74 0.76 1 0.76 0.76 nb_paires_opposees
10.17 5.39 0.66 1 0.66 0.66 nb_facons_rendre
6.37 5.80 0.41 6017 0.00 0.00 longueur
4.97 6.12 0.32 1 0.32 0.32 meilleure_periode
1.71 6.24 0.11 1 0.11 0.11 nb_clients_distincts
1.71 6.34 0.11 1 0.11 0.11 total_par_client
0.78 6.39 0.05 1 0.05 0.05 total_par_jour
0.39 6.42 0.03 30000 0.00 0.00 categorie
0.31 6.44 0.02 _init
0.00 6.44 0.00 149998 0.00 0.00 alea
0.00 6.44 0.00 6017 0.00 0.00 ajouter_ligne
0.00 6.44 0.00 1 0.00 0.00 empreinte
0.00 6.44 0.00 1 0.00 0.00 generer_transactions
Call graph
granularity: each sample hit covers 4 byte(s) for 0.16% of 6.44 seconds
index % time self children called name
<spontaneous>
[1] 99.7 0.00 6.42 main [1]
3.13 0.00 1/1 trier_par_montant [2]
0.85 0.00 30000/30000 rechercher_par_id [3]
0.76 0.00 1/1 nb_paires_opposees [4]
0.66 0.00 1/1 nb_facons_rendre [5]
0.00 0.41 6017/6017 ajouter_ligne [6]
0.32 0.00 1/1 meilleure_periode [8]
0.11 0.00 1/1 nb_clients_distincts [9]
0.11 0.00 1/1 total_par_client [10]
0.05 0.00 1/1 total_par_jour [11]
0.03 0.00 30000/30000 categorie [12]
0.00 0.00 1/1 generer_transactions [16]
0.00 0.00 1/1 empreinte [15]
-----------------------------------------------
3.13 0.00 1/1 main [1]
[2] 48.6 3.13 0.00 1 trier_par_montant [2]
-----------------------------------------------
0.85 0.00 30000/30000 main [1]
[3] 13.2 0.85 0.00 30000 rechercher_par_id [3]
-----------------------------------------------
0.76 0.00 1/1 main [1]
[4] 11.8 0.76 0.00 1 nb_paires_opposees [4]
-----------------------------------------------
266723738 nb_facons_rendre [5]
0.66 0.00 1/1 main [1]
[5] 10.2 0.66 0.00 1+266723738 nb_facons_rendre [5]
266723738 nb_facons_rendre [5]
-----------------------------------------------
0.00 0.41 6017/6017 main [1]
[6] 6.4 0.00 0.41 6017 ajouter_ligne [6]
0.41 0.00 6017/6017 longueur [7]
-----------------------------------------------
0.41 0.00 6017/6017 ajouter_ligne [6]
[7] 6.4 0.41 0.00 6017 longueur [7]
-----------------------------------------------
0.32 0.00 1/1 main [1]
[8] 5.0 0.32 0.00 1 meilleure_periode [8]
-----------------------------------------------
0.11 0.00 1/1 main [1]
[9] 1.7 0.11 0.00 1 nb_clients_distincts [9]
-----------------------------------------------
0.11 0.00 1/1 main [1]
[10] 1.7 0.11 0.00 1 total_par_client [10]
-----------------------------------------------
0.05 0.00 1/1 main [1]
[11] 0.8 0.05 0.00 1 total_par_jour [11]
-----------------------------------------------
0.03 0.00 30000/30000 main [1]
[12] 0.4 0.03 0.00 30000 categorie [12]
-----------------------------------------------
<spontaneous>
[13] 0.3 0.02 0.00 _init [13]
-----------------------------------------------
0.00 0.00 149998/149998 generer_transactions [16]
[14] 0.0 0.00 0.00 149998 alea [14]
-----------------------------------------------
0.00 0.00 1/1 main [1]
[15] 0.0 0.00 0.00 1 empreinte [15]
-----------------------------------------------
0.00 0.00 1/1 main [1]
[16] 0.0 0.00 0.00 1 generer_transactions [16]
0.00 0.00 149998/149998 alea [14]
-----------------------------------------------
Index by function name
[13] _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
[12] categorie [9] nb_clients_distincts [11] total_par_jour
[15] empreinte [5] nb_facons_rendre [2] trier_par_montant
+99
View File
@@ -0,0 +1,99 @@
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
48.60 3.13 3.13 1 3.13 3.13 trier_par_montant
13.20 3.98 0.85 30000 0.00 0.00 rechercher_par_id
11.80 4.74 0.76 1 0.76 0.76 nb_paires_opposees
10.17 5.39 0.66 1 0.66 0.66 nb_facons_rendre
6.37 5.80 0.41 6017 0.00 0.00 longueur
4.97 6.12 0.32 1 0.32 0.32 meilleure_periode
1.71 6.24 0.11 1 0.11 0.11 nb_clients_distincts
1.71 6.34 0.11 1 0.11 0.11 total_par_client
0.78 6.39 0.05 1 0.05 0.05 total_par_jour
0.39 6.42 0.03 30000 0.00 0.00 categorie
0.31 6.44 0.02 _init
0.00 6.44 0.00 149998 0.00 0.00 alea
0.00 6.44 0.00 6017 0.00 0.00 ajouter_ligne
0.00 6.44 0.00 1 0.00 0.00 empreinte
0.00 6.44 0.00 1 0.00 0.00 generer_transactions
Call graph
granularity: each sample hit covers 4 byte(s) for 0.16% of 6.44 seconds
index % time self children called name
<spontaneous>
[1] 99.7 0.00 6.42 main [1]
3.13 0.00 1/1 trier_par_montant [2]
0.85 0.00 30000/30000 rechercher_par_id [3]
0.76 0.00 1/1 nb_paires_opposees [4]
0.66 0.00 1/1 nb_facons_rendre [5]
0.00 0.41 6017/6017 ajouter_ligne [6]
0.32 0.00 1/1 meilleure_periode [8]
0.11 0.00 1/1 nb_clients_distincts [9]
0.11 0.00 1/1 total_par_client [10]
0.05 0.00 1/1 total_par_jour [11]
0.03 0.00 30000/30000 categorie [12]
0.00 0.00 1/1 generer_transactions [16]
0.00 0.00 1/1 empreinte [15]
-----------------------------------------------
3.13 0.00 1/1 main [1]
[2] 48.6 3.13 0.00 1 trier_par_montant [2]
-----------------------------------------------
0.85 0.00 30000/30000 main [1]
[3] 13.2 0.85 0.00 30000 rechercher_par_id [3]
-----------------------------------------------
0.76 0.00 1/1 main [1]
[4] 11.8 0.76 0.00 1 nb_paires_opposees [4]
-----------------------------------------------
266723738 nb_facons_rendre [5]
0.66 0.00 1/1 main [1]
[5] 10.2 0.66 0.00 1+266723738 nb_facons_rendre [5]
266723738 nb_facons_rendre [5]
-----------------------------------------------
0.00 0.41 6017/6017 main [1]
[6] 6.4 0.00 0.41 6017 ajouter_ligne [6]
0.41 0.00 6017/6017 longueur [7]
-----------------------------------------------
0.41 0.00 6017/6017 ajouter_ligne [6]
[7] 6.4 0.41 0.00 6017 longueur [7]
-----------------------------------------------
0.32 0.00 1/1 main [1]
[8] 5.0 0.32 0.00 1 meilleure_periode [8]
-----------------------------------------------
0.11 0.00 1/1 main [1]
[9] 1.7 0.11 0.00 1 nb_clients_distincts [9]
-----------------------------------------------
0.11 0.00 1/1 main [1]
[10] 1.7 0.11 0.00 1 total_par_client [10]
-----------------------------------------------
0.05 0.00 1/1 main [1]
[11] 0.8 0.05 0.00 1 total_par_jour [11]
-----------------------------------------------
0.03 0.00 30000/30000 main [1]
[12] 0.4 0.03 0.00 30000 categorie [12]
-----------------------------------------------
<spontaneous>
[13] 0.3 0.02 0.00 _init [13]
-----------------------------------------------
0.00 0.00 149998/149998 generer_transactions [16]
[14] 0.0 0.00 0.00 149998 alea [14]
-----------------------------------------------
0.00 0.00 1/1 main [1]
[15] 0.0 0.00 0.00 1 empreinte [15]
-----------------------------------------------
0.00 0.00 1/1 main [1]
[16] 0.0 0.00 0.00 1 generer_transactions [16]
0.00 0.00 149998/149998 alea [14]
-----------------------------------------------
Index by function name
[13] _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
[12] categorie [9] nb_clients_distincts [11] total_par_jour
[15] empreinte [5] nb_facons_rendre [2] trier_par_montant
File diff suppressed because it is too large Load Diff
+6017
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
rabot;-;2372
1 rabot - 2372
+6
View File
@@ -0,0 +1,6 @@
Clients distincts : 2000
Somme des requêtes : -2624578
Meilleure période : jours 650 à 986 (3548830)
Paires opposées : 5832
Façons de rendre 400 : 1960497
Empreinte : ff68d260a7a58441
+3
View File
@@ -0,0 +1,3 @@
real 2.43
user 2.39
sys 0.00
+16
View File
@@ -0,0 +1,16 @@
# Analyse des fonctions avec valeurs initiales
| ID | 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ⁿ)` | `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 |
`n` transactions · `C` clients · `J` jours · `S` somme · `k` pièces · `L` longueur du rapport · **F5, F7, F8** : les plus difficiles