Adloun

informatique (MP2I/MPI) · Chapitre 6 · Exercice de TD

Problème — Un ensemble d'entiers, trois réalisations, un critère

Types et structures de données abstraites · niveau 3 (difficile)

Énoncé

On veut le contrat : vide, ajouter, appartient, cardinal, sur des entiers de .

  • Écrire la réalisation par liste non triée, par liste triée, et par tableau de booléens.
  • Donner la complexité de chaque opération dans chaque cas.
  • Mesurer, et expliquer l'écart.
  • Sur quel critère choisit-on ?

Corrigé

1. Les trois réalisations.


(* A. liste NON triee, sans doublon *)
let a_vide = []
let a_appartient x s = List.mem x s
let a_ajouter x s = if List.mem x s then s else x :: s

(* B. liste TRIEE sans doublon *)
let rec b_appartient x = function
  | [] -> false        | y :: _ when x = y -> true
  | y :: _ when x < y -> false      (* triee : inutile d'aller plus loin *)
  | _ :: r -> b_appartient x r
let rec b_ajouter x = function
  | [] -> [x]
  | y :: r when x < y -> x :: y :: r
  | y :: r when x = y -> y :: r
  | y :: r -> y :: b_ajouter x r

(* C. vecteur caracteristique : une case par valeur possible *)
let c_vide () = Array.make u false
let c_appartient x s = s.(x)
let c_ajouter x s = s.(x) <- true

2. Les coûts, pour un ensemble de éléments pris dans :

appartientajoutercardinalMémoire
A. liste non triée
B. liste triée
C. tableau de booléens

Noter que B ne gagne aucun ordre sur A : la recherche s'arrête plus tôt en moyenne, mais elle parcourt toujours. C'est l'objet du huitième exercice de ce chapitre.

3. La mesure, pour insertions suivies de recherches, avec :


n =  1000 : A 0,025 s    B 0,027 s    C 0,004 s
n =  5000 : A 0,581 s    B 0,653 s    C 0,004 s
n = 20000 : A 9,347 s    B 11,092 s   C 0,007 s

Quand est multiplié par , le temps de A et B est multiplié par : coût quadratique, conforme à opérations en . Celui de C ne bouge pas : opérations en , et le temps est dominé par l'allocation des cases, qui ne dépend pas de .

B est même légèrement plus lente que A — contre secondes. L'insertion triée doit reconstruire le préfixe de la liste jusqu'au point d'insertion, alors que l'insertion en tête ne fabrique qu'un maillon. Le tri se paye à l'écriture ce qu'il rapporte à la lecture, et sur une chaîne il ne rapporte qu'un facteur constant.

4. Le critère. Il tient au rapport :

  • Si est petit et connu d'avance — des jours de l'année, des codes ASCII, des sommets d'un graphe —, le vecteur caractéristique gagne toujours, et il gagne de plusieurs ordres. C'est la structure la plus sous-employée du programme.
  • Si est immense ou inconnu — des chaînes de caractères, des entiers quelconques —, le vecteur est impossible et l'on veut une table de hachage : en moyenne pour un espace , chapitre chap:hachage.
  • La liste triée ne se justifie que si l'on a besoin de parcourir les éléments dans l'ordre, ce que ni A ni C ne donnent gratuitement.

Et c'est la démonstration de la thèse du chapitre : le contrat n'a pas changé, l'algorithme utilisateur n'a pas changé, et le temps a été divisé par mille. « Le développement d'un algorithme va de pair avec la conception d'une structure de données taillée à la mesure du problème. »

Exercices semblables

Le cours du chapitre · Tous les exercices du chapitre