• Aucun résultat trouvé

Un algorithme de tri est, en informatique ou en mathématiques, un algorithme qui permet d'organiser une collection d'objets selon un ordre déterminé. Les objets à trier font donc partie d'un ensemble muni d'une relation d'ordre (de manière générale un ordre total). Les ordres les plus utilisés sont l’ordre numérique et l'ordre lexicographique (dictionnaire). Suivant la relation d'ordre considérée, une même collection d’objet peut donner lieu à divers arrangements, pourtant il est possible de définir un algorithme de tri indépendamment de la fonction d’ordre utilisée. Celui-ci ne fera qu'utiliser une certaine fonction d’ordre correspondant à une relation d’ordre qui doit permettre de comparer tout couple d'éléments de la collection.

13.1. Tri à bulles

Le tri à bulles ou tri par propagation est un algorithme de tri qui consiste à faire remonter progressivement les plus petits éléments d'une liste, comme les bulles d'air remontent à la surface d'un liquide. L'algorithme parcourt la liste, et compare les couples d'éléments successifs. Lorsque deux éléments successifs ne sont pas dans l'ordre croissant, ils sont échangés. Après chaque parcours complet de la liste, l'algorithme recommence l'opération. Lorsqu'aucun échange n'a lieu pendant un parcours, cela signifie que la liste est triée : l'algorithme peut s'arrêter.

Cet algorithme est souvent enseigné en tant qu'exemple algorithmique. Cependant, il présente une complexité en О(n²) dans le pire des cas (où n est la longueur de la liste), ce qui le classe parmi les mauvais algorithmes de tri. Il n'est donc quasiment pas utilisé en pratique.

Syntaxe :

Const MAX = 100; (* MAX = 100 est donné en exemple seulement *) Type tab = array [1..MAX] of integer;

Procedure TriBulle(n: integer ; var t: tab); Var i, j, tmp: integer;

begin

(* On va trier les n-1 premiers éléments du tableau *) for i := 1 to n - 1 do

begin

for j := 1 to n - i do (* on fait n-i-1 comparaisons en avançant dans le tableau *) begin if(t[j + 1] < t[j]) then begin tmp := t[j]; t[j] := t[j + 1]; t[j+1] := tmp; end; end; end; end;

13.2. Tri par sélection

Le tri par sélection (ou tri par extraction) est un des algorithmes de tri les plus triviaux. Il consiste en la recherche soit du plus grand élément (ou le plus petit) que l'on va replacer à sa position finale c'est-à-dire en dernière position (ou en première), puis on recherche le second plus grand élément (ou le second plus petit) que l'on va replacer également à sa position finale c'est-à-dire en avant-dernière position (ou en seconde), etc., jusqu'à ce que le tableau soit entièrement trié.

Le tri par sélection est intéressant lorsque les éléments sont aisément comparables mais coûteux à déplacer dans la structure. Ainsi, le nombre de comparaisons sera toujours supérieur ou égal à ce qui est nécessaire pour effectuer un tri par insertion ou un tri à bulles. Par contre, s'il n'est pas possible de faire des insertions dans la structure en temps constant (O(1)), le nombre d'échanges sera en moyenne très inférieur.

Syntaxe :

procedure TriSelection(n : integer ; var t : tab); var i, j, min, tmp : integer;

begin

for i := 1 to n - 1 do begin min := i;

for j := i + 1 to n do

if (t[j] < t[min]) then min:=j;

if (i <> min) then begin tmp := t[i]; t[i] := t[min]; t[min] := tmp; end; end; end;

13.3. Tri par insertion

Le tri par insertion est le tri le plus efficace sur des listes de petite taille. C'est pourquoi il est utilisé par d'autres méthodes comme le tri rapide (ou quicksort). Il est d'autant plus rapide que les données sont déjà triées en partie dans le bon ordre.

Le principe de ce tri est très simple: c'est le tri que toute personne utilise naturellement quand elle a des dossiers (ou n'importe quoi d'autre) à classer. On prend un dossier et on le met à sa place parmi les dossiers déjà triés. Puis on recommence avec le dossier suivant.

Pour procéder à un tri par insertion, il suffit de parcourir une liste : on prend les éléments dans l'ordre. Ensuite, on les compare avec les éléments précédents jusqu'à trouver la place de l'élément qu'on considère. Il ne reste plus qu'à décaler les éléments du tableau pour insérer l'élément considéré à sa place dans la partie déjà triée. On peut aussi faire une recherche par dichotomie sur les tableaux.

Syntaxe :

const MAX = 100;

type tab = array [1..MAX] of real;

Procedure TriInsertion(n : integer ; var t : tab); var i, j : integer;

var z : real; begin

for i:=2 to n do begin

z := t[i]; (* z est la valeur à insérer *)

(* dans l'endroit approprié du tableau *) (* On décale toutes les valeurs du tableau < z *) (* à droite pour vider une place pour z *) j := i - 1;

while (j >= 1) and (t[j] > z) do begin t[j + 1] := t[j];

j := j - 1; end;

(* finalement la valeur z est insérée à son emplacement adéquat *) t[j + 1] := z;

end; end;

13.4. Tri rapide

Le tri rapide (en anglais quicksort) est une méthode de tri inventée par C.A.R. Hoare en 1961 et fondée sur la méthode de conception diviser pour régner. Il peut être implémenté sur un tableau (tri sur place) ou sur des listes ; son utilisation la plus répandue concerne tout de même les tableaux.

Le Quicksort est un tri dont la complexité moyenne est en , mais dont la complexité dans le pire des cas est O(n2). Malgré ce désavantage théorique, c'est en pratique un des tris sur place le plus rapide pour des données réparties aléatoirement. Les entrées donnant lieu au comportement quadratique dépendent de l'implémentation de l'algorithme, mais sont souvent (si l'implémentation est maladroite) les entrées déjà presque triées. Il sera plus avantageux alors d'utiliser le tri par insertion.

Syntaxe :

const MAX_VAL = 200;

type tab_entier = array [1..MAX_VAL] of integer; procedure tri_rapide(deb, fin : integer ; var t : tab_entier); var i, p : integer; mid, aux : integer;

begin

(* si fin > deb alors le tableau nécessite d'être trié*) if (fin > deb) then begin

(* choisir le milieu du tableau comme pivot *) mid := (deb + fin) div 2;

(* mettre l'élément pivot au début afin de pouvoir parcourir le tableau en continu. *) aux := t[mid];

t[mid] := t[deb]; t[deb] := aux;

(* parcourir le tableau tout en amenant les éléments inférieurs à l'élément pivot au début de la plage *)

p := deb;

for i:=deb+1 to fin do begin if (t[i] < t[deb]) then begin p := p + 1; aux := t[i]; t[i] := t[p]; t[p] := aux; end; end;

(* mettre le pivot à la position adéquate càd à la suite des éléments qui lui sont inférieurs *) aux := t[p];

t[p] := t[deb]; t[deb] := aux;

tri_rapide(deb, p - 1, t); (* trie le sous tableau à gauche *) tri_rapide(p + 1, fin, t); (* trie le sous tableau à droite *) end;

ChapitreII. MATLAB

Introduction

MATLAB (MATrix LABoratory) comprend de nombreuses fonctions graphiques, un système puissant d’operateurs s’appliquant à des matrices, des algorithmes numériques (EDOs, zéros d’une fonction, intégration, interpolation), ainsi qu’un langage de programmation extrêmement simple à utiliser.

Il fut conçu initialement (au milieu des années 1980) pour manipuler aisément des matrices à l’aide de fonctions préprogrammées (addition, multiplication, inversion, décompositions, déterminants . . .), en s’affranchissant des contraintes des langages de programmation classique :

– Plus de déclarations de variables.

– Plus de phase d’édition-compilation-exécution.

Cette orientation calcul matriciel a depuis évolue vers un outil pouvant être vu comme une super-calculatrice graphique et regroupant dans la version de base la quasi-majorité des problèmes numériques (hormis les EDP qui sont aussi diversifiées que délicates à résoudre). Plusieurs extensions plus «pointues» ont été conçues sous la forme de «TOOLBOX», qui sont des paquets (payants parfois …!) de fonctions supplémentaires dédiées à un domaine particulier :

– CONTROL pour l’automatique. – SIGNAL pour le traitement du signal. – OPTIMIZATION pour l’optimisation.

Cet aspect modulaire est l’un des plus grands atouts de MATLAB : l’utilisateur peut lui- même définir ses propres fonctions, en regroupant des instructions MATLAB dans un fichier portant le suffixe “.m”. La syntaxe est bien plus abordable que dans les langages classiques et devrait éliminer les réticences habituelles des programmeurs débutants pour écrire des fonctions.

En termes de vitesse d’exécution, les performances sont inférieures à celles obtenues avec un langage de programmation classique. L’emploi de MATLAB devrait donc être restreinte à des problèmes peu gourmands en temps calcul, mais dans la plupart des cas, il présente une solution élégante et rapide à mettre en œuvre.

Notons enfin que MATLAB est disponible sur tous types de plates-formes (toutes les stations sous UNIX y compris LINUX, Windows 9x et Macintosh).

Documents relatifs