23

Projet ALGORITHMES AVANCES Tri par différents structures de données

  • Upload
    uh1

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

1

EL BAHRI Tahar

ALGORITHMES AVANCES

Tri par différents structures de données

2

Mr. Imad HAFIDI

Remerciement

Avant d’entamer ce rapport, mes remerciements s’adressent en premier lieu

à mon encadrant Mr. Imad HAFIDI qui nous a formé et accompagné tout au

long de la préparation de ce projet avec beaucoup de patience et de pédagogie.

Qu’il retrouve ici mes profondes gratitudes pour leur disponibilité, leurs

directives précieuses et leur aide durant notre formation. Je les remercie aussi

pour leur patience, leur dévouement permanent, leurs conseils pertinents et leur

encadrement direct et amical de ce projet sans lequel ce travail n’aurait pas

abouti.

Je remercie aussi très sincèrement mes camarades de classe qui m’ont aidé

- de près ou de loin - pour terminer ce travail.

3

Contexte du projet

Dans le cadre du module d’algorithmes avancées, et après avoir acquis des

connaissances approfondies en algorithmique et langage C, nous avons été amené

à réaliser un simulateur de tri en utilisant différents structures de données vues en

cours : Tableau, Liste chainées, Arbres binaire de recherche, AVL, Tas ….

Problématique de tri

Depuis l’avènement de l’informatique, les ordinateurs sont capables de traiter

des quantités d’informations de plus en plus importantes. Actuellement, un

simple ordinateur de bureau n’a rien à envier aux gros ordinateurs à peine plus

âgés qu’eux. Mais la capacité des ordinateurs à effectuer des traitements de plus

en plus importants n’est pas uniquement due à l’évolution physique des

machines.

Le traitement de données de masse pose le problème de leur classement. C’est

pour cela que différentes méthodes de tris ont été développées. L’étude des tris

est un problème intéressant puisque c’est l’un des domaines de l’algorithmique

qui a été le plus étudié. Cette étude permet également d’aborder de façon

concrète les problèmes de complexité des algorithmes. Ainsi, pour un problème

simple et unique, le tri d’un tableau de données, de nombreuses solutions existent.

Malheureusement, seules quelques-unes d’entre elles sont assez performantes

pour supporter le traitement d’un nombre élevé de valeurs.

4

Table des matières

5

Chapitre I : Structure de données

Une table est une structure de données telle que l’accès à un élément est déterminé à partir

de sa clé. La clé permet d’identifier un élément de manière unique, la clé (un entier ou une

chaîne alphanumérique) est dite discriminante. Dans la suite de ce chapitre, on n’envisage

pas les cas où une même clé peut correspondre à plusieurs éléments. Connaissant la clé,

on peut retrouver l’élément et ses caractéristiques. L’allocation d’espace pour une table est

souvent contiguë. Il faut réserver l’espace mémoire en début de traitement (en mémoire

centrale ou sur mémoire secondaire).

Méthodes de tri

1. Tri par sélection

Définition et caractéristiques

6

Le principe du tri par sélection est le suivant. On sélectionne le maximum (le plus grand)

de tous les éléments, et on le place en dernière position n-1 par un échange. Il ne reste plus

qu’à trier les n-1 premiers éléments, pour lesquels on itère le procédé.

Exemple :

Grandes étapes de l’évolution du tableau au fil de l’algorithme.

En bleu, les valeurs déjà traitées.

Algorithme :

2. Tri par insertion

Le principe du tri par insertion est le suivant : on trie d’abord les deux premiers éléments,

puis on insère le 3ème à sa place pour faire une liste triée de 3 éléments, puis on insère le

4ème élément dans la liste triée. La liste triée grossit jusqu’à contenir les n éléments.

Exemple :

Grandes étapes de l’évolution du tableau au fil

de l’algorithme. En bleu, le tableau trié, en rouge,

la valeur de la mémoire qui contient la valeur

à insérer.

7

Algorithme :

3. Tri par fusion

Le tri fusion est construit suivant la stratégie "diviser pour régner", en anglais "divide and

conquer". Le principe de base de la stratégie "diviser pour régner" est que pour résoudre un

gros problème, il est souvent plus facile de le diviser en petits problèmes élémentaires.

Une fois chaque petit problème résolu, il n’y a plus qu’à combiner les différentes solutions

pour résoudre le problème global. La méthode "diviser pour régner" est tout à fait

applicable au problème de tri : plutôt que de trier le tableau complet, il est préférable de

trier deux sous tableaux de taille égale, puis de fusionner les résultats.

Exemple :

Grandes étapes de l’évolution du

tableau au fil de l’algorithme :

8

Algorithme :

algorithme TRI-FUSION(@T,g,d);

données

T: tableau de valeurs;

g,d: entiers;

variables

p: entier;

debut

SI (g < d) ALORS

p ← (g + d) / 2;

TRI-FUSION(T,g,p);

TRI-FUSION(T,p + 1,d);

FUSIONNER(@T,g,p,d);

FSI

fin.

4. Tri rapide

L’algorithme de tri rapide, "quick sort" en anglais, est un algorithme de type

dichotomique. Son principe consiste à séparer l’ensemble des éléments en deux parties. La

différence par rapport au tri fusion, vu précédemment, est que la séparation des différentes

valeurs ne s’effectue pas n’importe comment. Pour effectuer la séparation, une valeur pivot

est choisie. Les valeurs sont réparties en deux ensembles suivant qu’elles sont plus grandes ou

plus petites que le pivot. Ensuite, les deux ensembles sont triés séparément, suivant la même

méthode.

Exemple :

Grandes étapes de l’évolution du tableau au

fil de l’algorithme : En bleu, les valeurs déjà

positionnées, en rose, les valeurs qui servent

de pivot pour passer à la ligne suivante.

9

Algorithme :

5. Tri par shell

Le tri par insertion provoquait le décalage de tous les éléments plus grands que l’élément à

insérer. Dans le tri Shell, les éléments ne sont pas décalés d’un élément à la fois, mais de

plusieurs éléments, dont la différence d’indice est appelée "pas". Ainsi, à chaque étape, le tri

est dégrossit puis le pas est réduit. Chaque réduction de pas provoque un affinage du tri.

Lorsque le pas atteint la valeur 1, cela revient à effectuer le tri par insertion.

Cependant, cette fois, le tri par insertion est appliqué à un tableau possédant un certain

ordre (provoqué par les étapes de préparations où le pas est supérieur à un). En effet, les

différentes étapes où le pas est supérieur à un provoque le regroupement des différentes

valeurs par groupes de la même taille que le pas.

10

Exemple :

Évolution du tableau au fil du tri shell. Le pas,

représenté en rouge est également indiqué ainsi

que la valeur en mémoire, sur laquelle porte la

comparaison. En bleu, les valeurs sur lesquels

portent les comparaisons à chaque étape.

Algorithme :

Une pile est une structure de données dans laquelle on peut ajouter et supprimer des

éléments suivant la règle du dernier arrivé premier sorti ou encore LIFO (Last In First Out).

Une file est une structures de données dans laquelle on peut ajouter et supprimer des

éléments suivant la règle du premier arrivé premier sorti, ou encore FIFO (First In First

Out).

Définition et caractéristiques

11

Définition et caractéristiques

Une liste chaînée (voir figure 19.1) est un ensemble de cellules liées entre elles par des

pointeurs. Chaque cellule est une structure contenant les champs suivants :

• une ou plusieurs données comme dans n’importe quelle structure

• un pointeur suivant sur la cellule suivante

On accède à la liste par un pointeur L sur la première cellule, puis en parcourant la liste

d’une cellule à l’autre en suivant les pointeurs suivant. Le dernier pointeur suivant vaut

NULL, ce qui indique la fin de la liste.

Méthodes de tri

12

Définition et caractéristiques

Un arbre est une structure de données composée d’un ensemble de nœuds.

Chaque nœud contient l’information spécifique de l’application et des pointeurs vers d’autres

nœuds (d’autres sous-arbres).

Un arbre binaire est un arbre ordonné tel que chaque nœud a au plus deux fils et quand il n’y

en a qu’un, on distingue le fils droit du fils gauche.

C'est un des arbres les plus simples, et nous allons le simplifier au maximum. Ses éléments

(ou nœuds) ne contiendront qu'une valeur de type entier.

Méthodes de tri

Le tri par Arbre Binaire de Recherche est un tri classé à part, non pas parce qu’il est plus

performant, mais parce qu’il nécessite quelques connaissances sur une structure particulière

appelée "arbre". Un arbre est une structure composée d’une racine et plusieurs pointeurs

vers d’autres arbres ou vers une feuille. Une feuille est un arbre particulier qui ne possède

aucun sous arbre, c’est un arbre terminal. Un nœud est la racine d’un sous arbre. L’exemple

ci-dessous illustre le vocabulaire qui viens d’être décrit.

Dans les tris précédents, nous avons déja eu l’occasion de

manipuler une structure de type "arbre". Il s’agit des listes,

qui sont une forme d’arbre particuliére puisque chaque

noeud n’est rattaché qu’à un seul sous arbre : une liste est

une structure comportant une valeur et un pointeur vers

une autre liste.

Les arbres qui nous intéressent ici sont appelés arbres

binaires de recherches (ou ABR). "binaire" car ils ne

peuvent posséder que deux sous arbres et "de recherche" car les valeurs situées dans le sous

arbre gauche d’un ABR sont toutes inférieures à la valeur du nœud de l’arbre, et celles

situées dans le sous arbre droit lui sont supérieures. Construction de l’arbre binaire de

recherche :

Pour réaliser ce tri il faut tout d’abord construire l’arbre binaire de recherche

correspondant aux éléments à classer. C’est ce qui va être fait ici. La première valeur de

13

l’ensemble fera office de racine. Ensuite, pour construire l’arbre binaire, il faut descendre

dans l’arbre en comparant les différents éléments à la racine.

Définition et caractéristiques

Un tas est un tableau A qui peut être vu comme un arbre binaire presque complet. Chaque

nœud de l’arbre correspond à un élément du tableau qui contient la valeur du nœud.

L’arbre est complétement rempli à tous les niveaux, sauf, parfois, sur le plus bas, rempli à

partir de la gauche, jusqu‘`a un certain point.

Méthodes de tri

L’algorithme du tri par tas commence par utiliser CONSTRUIRE-TAS-MAX pour

construire un tas max à partir du tableau A[1 . . n], où n = longueur[A]. Comme l’élément

maximal du tableau est stocké à la racine A[1], on peut le placer dans sa position finale

correcte en l’échangeant avec A[n]. Si l’on « ôte » à présent le nœud n du tas (en

décrémentant taille[A]), on observe que A[1 . . (n − 1)] peut facilement être transformé en tas

max. Les enfants de la racine restent des tas max, mais la nouvelle racine risque d’enfreindre

la propriété de tas max. Pour restaurer la propriété de tas max, il suffit toutefois d’appeler

une seule fois ENTASSER-MAX(A, 1) qui laisse un tas max dans A[1 . . (n − 1)].

L’algorithme du tri par tas répète alors ce processus pour le tas max de taille n − 1 jusqu’à

arriver à un tas de taille 2.

14

Définition et caractéristiques

Un arbre AVL (Adelson-Velskii-Landis) est un arbre binaire de recherche H-équilibré. En

tant qu'arbre binaire de recherche, on peut utiliser l'algorithme des arbres binaires de

recherche pour la recherche ; il aura une complexité de , vu la propriété.

Pour l'insertion, on procèdera comme pour un arbre binaire classique) ; ensuite, on

rétablira l'invariant au besoin à l'aide de rotations.

Méthodes de tri

On peut utiliser un arbre AVL pour le tri : on insère successivement les éléments dans

l'arbre et on effectue un parcours en ordre. On aura une complexité temporelle optimale

mais une complexité en espace linéaire (on doit allouer un arbre).

Chapitre 11 : Conception du Programme

L’application de tri qu’on réaliser en langage C contient pour chaque structure de données

un fichier .h qui représente sa structure et ses fonctions et un fichier .c qui contient un menu

de cette structure et qui implémente ses fonctions.

Un fichier de simulation .c (main.c) qui contient le menu principal de l’application cette

dernière demande à l’utilisateur de choisir la structure de données pour la simulation :

Le menu principal : (choix de la structure de simulation)

15

Demande de la taille de l’ensemble de valeurs : (Pile comme exemple)

Le mode de saisie (mode simulation manuelle) ou génération automatique :

16

Le menu secondaire de chaque structure de données : (choix opération)

17

L’affichage des résultats de tri :

18

CHAPITRE III : Résultats et Discussion

La plus part résultats est présenter dans la partie de conception du programme.

Concernant la fonction time qui calcul le temps d’exécution de tri je ne pouvais pas la

intégrés dans l’application mais j'ai réussi de construire des programme pour faire une

comparaison entre certain algorithme de tri.

Le code C de la fonction time :

La courbe de tri par ABR est la suivant :

19

La courbe de tri par tas est la suivante :

Ces résultats est totalement différents des résultats théorique.

Pour interprétation de cette résultat je vous explique la fonction time qui calcul le temps

d’exécution de tri.

La fonction Time est une fonction de la charge de calcul de votre machine : elle fluctue. Un

programme fonctionnant seul sur une machine peut avoir un temps d’exécution de 10 min

alors que le temps d’exécution passera à 14 min si la machine est utilisée à surfer sur

internet pendant le déroulement des calculs.

Le CPU Time est le temps passé par un programme sur le processeur. Ce temps est une

constante : il ne dépend pas de la charge de travail de votre machine.

Lorsqu’on mesure les performances d’un algorithme de tri on a tendance à mesurer le User

Time alors que cela est une erreur surtout si on travaille sur une station de travail multi-

utilisateurs.

Sous Windows, dès que la machine est sollicitée (ouverture de fichier etc.) à des tâches

annexes (dès qu’on utilise un peu le PC sur lequel le programme tourne) le User Time sera

très différent du CPU Time et ceci dans des proportions importantes : surfer sur internet

pendant les calculs impacte de 6-10% le User Time.

20

Une étude publiée sur le site web http://tablesort.99k.org/comparaison.html montre

la différence entre différents algorithme de tri voici une résumé de cette étude :

Après avoir programmé les 6 méthodes en générant de façon aléatoire des tableaux de

nombres, nous avons mesuré les temps d'exécution pour chaque méthode.

Ces temps d'exécution ne sont pas très précis; ils ont une précision de l'ordre de 40% pour

une mesure d'une seconde; cette précision baisse à 5% quand la mesure depasse 200

secondes. Les temps servent toutefois d'éléments de comparaison, soit entre méthodes de tris,

soit entre tailles différentes.

21

Conclusion

Le bilan est que j’ai présument les objectifs fixés en début de projet. Pour

conclure, on peut dire que ce projet a été particulièrement intéressant.

D’un point de vue pédagogique, le fait de devoir créer une application me a

permis de comprendre encore mieux le fonctionnement des algorithmes de tri et

les structures de données.

En ce qui concerne l’aspect programmation, même s’il ne s’agit pas du but

principal, il s’avère que ce projet me a permis de mettre en application un certain

nombre de connaissances apprises dans des semestres précédentes y compris la

programmation en langage C.

22

Des livres et des ouvrages :

Algorithmes et structures de données génériques

[Michel Divay] Algorithmes et structures de donné

[Rémy Malgouyres – Rita Zrour - Fabien Feschet] INITIATION

L’ALGORITHMIQUE ET À LA PROGRAMMATION

[Caroline Prodhon - Philippe Lacomme - Ren Libo] Comment mesurer les

temps de calcul

Des sites web :

http://www.dailly.info/-030-Algorithmes-de-Tri-

http://fr.openclassrooms.com/

http://www.developpez.com/

http://tablesort.99k.org/comparaison.html

http://fr.wikipedia.org/wiki/Algorithme_de_tri

Bibliographie