Vous êtes sur la page 1sur 57

Initiation l'algorithmique

par Denis Lapoire

Ce document est un cours d'initiation l'algorithmique qui permettra toute personne de pouvoir mettre en oeuvre les notions et concepts de bases de l'algorithmique dans leur programme et permettra aux plus expriments de voir et concevoir leurs algorithmes diffremment.

Initiation l'algorithmique par Denis Lapoire

I - TABLE DES MATIRES........................................................................................................................................ 4 II - Chapitre 1 Discours de la Mthode(extraits).........................................................................................................5 III - Chapitre 2 Quelques dfinitions et quelque syntaxe............................................................................................5 III-A - 2.1 Problmes............................................................................................................................................. 5 III-B - 2.2 Types.....................................................................................................................................................6 III-C - 2.3 Algorithme............................................................................................................................................. 6 III-C-1 - 2.3.1 Entte de l'algorithme................................................................................................................7 III-C-2 - 2.3.2 Le corps de l'algorithme............................................................................................................ 7 III-C-3 - 2.3.3 Variable......................................................................................................................................7 III-C-4 - 2.3.4 valuation d'expression............................................................................................................. 8 III-C-5 - 2.3.5 Initialisation................................................................................................................................ 9 III-C-6 - 2.3.6 Modification de valeurs..............................................................................................................9 III-C-7 - 2.3.7 Mise en squence..................................................................................................................... 9 III-C-8 - 2.3.8 Branchement conditionnel....................................................................................................... 10 III-C-9 - 2.3.9 Autres branchements conditionnels.........................................................................................10 III-C-10 - 2.3.10 Boucle.................................................................................................................................. 10 III-C-11 - 2.3.11 Autres boucles..................................................................................................................... 12 III-C-12 - 2.3.12 Instruction retourner.............................................................................................................13 III-C-13 - 2.3.13 Appel de fonctions............................................................................................................... 14 III-C-14 - 2.3.14 Indentation........................................................................................................................... 16 III-D - 2.4 Conclusion...........................................................................................................................................17 IV - Chapitre 3 Problmes........................................................................................................................................ 18 IV-A - 3.1 Un premier exemple........................................................................................................................... 18 IV-B - 3.2 Un second exemple............................................................................................................................ 19 IV-C - 3.3 Comparaison de problmes................................................................................................................19 IV-C-1 - 3.3.1 Augmenter les contraintes en entre...................................................................................... 19 IV-C-2 - 3.3.2 Diminuer les contraintes en sortie.......................................................................................... 19 IV-C-3 - 3.3.3 Dcomposition en un ensemble quivalent de sous- problmes............................................ 20 V - Chapitre 4 Terminaison et complexits.............................................................................................................. 21 V-A - 4.1 Terminaison..........................................................................................................................................22 V-B - 4.2 Complexit........................................................................................................................................... 22 V-C - 4.3 Complexit d'une entre......................................................................................................................23 V-C-1 - 4.3.1 Complexit d'un boolen..........................................................................................................23 V-C-2 - 4.3.2 Complexit d'un entier............................................................................................................. 23 V-C-3 - 4.3.3 Complexit d'une matrice d'entiers.......................................................................................... 24 V-D - 4.4 Complexit d'un algorithme................................................................................................................. 24 V-D-1 - 4.4.1 Instruction lmentaire............................................................................................................. 24 V-D-2 - 4.4.2 Espace utilise par l'algorithme............................................................................................... 24 V-D-3 - 4.4.3 Complexit en temps dans le pire des cas..............................................................................25 V-D-4 - 4.4.4 Complexit en temps en moyenne.......................................................................................... 25 V-D-5 - 4.4.5 Complexit en temps dans le meilleur des cas....................................................................... 25 V-D-6 - 4.4.6 Complexit en espace..............................................................................................................26 V-E - 4.5 Complexit d'un problme................................................................................................................... 26 V-E-1 - 4.5.1 Compromis espace-temps........................................................................................................26 V-F - 4.6 Notations et simplifications.................................................................................................................. 26 V-F-1 - 4.6.1 une constante multiplicative prs: notation e........................................................................ 26 V-F-2 - 4.6.2 Des fonctions talons............................................................................................................... 28 V-F-3 - 4.6.3 Simple majoration : notation O................................................................................................. 28 V-F-4 - 4.6.4 Quelques rgles d'valuation de complexit............................................................................ 29 V-F-5 - 4.6.5 Mise en squence.................................................................................................................... 29 V-F-6 - 4.6.6 Branchement conditionnel........................................................................................................ 30 V-G - 4.7 Un peu de vocabulaire........................................................................................................................ 30 V-G-1 - 4.7.1 Un algorithme linaire.............................................................................................................. 30 V-G-2 - 4.7.2 Un algorithme exponentiel....................................................................................................... 30 V-H - 4.8 tude du problme de puissance........................................................................................................31 V-H-1 - 4.8.1 Importance des hypothses..................................................................................................... 32 VI - Chapitre 5 Algorithmes "Diviser Pour rgner"................................................................................................... 34 VI-A - 5.1 Un premier exemple : la multiplication de deux entiers...................................................................... 34
-2-

Initiation l'algorithmique par Denis Lapoire

VI-A-1 - 5.1.1 Un premier algorithme.............................................................................................................35 VI-A-2 - 5.1.2 Un second algorithme............................................................................................................. 35 VI-A-3 - 5.1.3 valuation de la complexit.................................................................................................... 36 VI-B - 5.2 valuation de la complexit................................................................................................................36 VI-B-1 - 5.2.1 Dfinition rcursive de la fonction........................................................................................... 36 VI-C - 5.3 Rsolution de certaines fonctions N - N dfinies rcursivement........................................................ 37 VI-D - 5.4 Un deuxime exemple : la multiplication de deux matrices................................................................38 VI-D-1 - 5.4.1 Premire mthode...................................................................................................................38 VI-D-2 - 5.4.2 Seconde mthode dite de Strassen........................................................................................38 VI-D-3 - 5.4.3 Conclusion...............................................................................................................................39 VII - Chapitre 6 Programmation Dynamique.............................................................................................................39 VII-A - 6.1 Une solution de programmation dynamique...................................................................................... 39 VII-A-1 - 6.1.1 Autre alternative..................................................................................................................... 40 VII-A-2 - 6.2 Bien fond de l'approche dynamique........................................................................................41 VIII - Chapitre 7 Algorithme Glouton........................................................................................................................ 42 VIII-A - 7.1 Un premier exemple : le rendu de monnaie..................................................................................... 42 VIII-A-1 - 7.1.1 Correction.............................................................................................................................. 42 VIII-A-2 - 7.1.2 Amlioration...........................................................................................................................43 VIII-B - 7.2 Deuxime exemple : optimisation de la location d'une salle.............................................................43 VIII-B-1 - 7.2.1 Premire tentavive.................................................................................................................43 VIII-B-2 - 7.2.2 Deuxime tentavive............................................................................................................... 43 VIII-B-3 - 7.2.3 Troisime tentavive concluante............................................................................................. 44 VIII-C - 7.3 Conclusion........................................................................................................................................ 44 IX - Chapitre 8 Quelques algorithmes de tri.............................................................................................................44 IX-A - 8.1 Approche gloutonne............................................................................................................................ 45 IX-B - 8.2 Une premire implmentation.............................................................................................................45 IX-C - 8.3 Une deuxime implmentation l'aide d'un tas................................................................................. 45 IX-C-1 - 8.3.1 Dfinition de haut niveau d'un tas...........................................................................................46 IX-C-2 - 8.3.2 Implmentation d'un tas.......................................................................................................... 46 IX-C-3 - 8.3.3 Ajouter un lment dans un tas..............................................................................................46 IX-C-4 - 8.3.4 Extraire le maximum dans un tas........................................................................................... 47 IX-C-5 - 8.3.5 Implmentation d'un tas-arbre l'aide d'un tableau................................................................47 IX-C-6 - 8.3.6 criture de l'algorithme........................................................................................................... 48 IX-C-7 - 8.3.7 valuation de la complexit.................................................................................................... 48 IX-D - 8.4 Approche "Diviser pour rgner".......................................................................................................... 50 IX-D-1 - 8.4.1 Premire solution algorithmique de TriRec............................................................................. 51 IX-D-2 - 8.4.2 Seconde solution algorithmique de TriRec............................................................................. 53 IX-D-3 - 8.4.3 Diffrentes variantes lies au choix du pivot.......................................................................... 54 IX-D-4 - 8.4.4 Le choix du premier pivot venu: le tri rapide...........................................................................55 IX-D-5 - 8.4.5 Le choix d'un pivot alatoire................................................................................................... 56 IX-D-6 - 8.4.6 Le choix d'un pivot mdian..................................................................................................... 56

-3-

Initiation l'algorithmique par Denis Lapoire

I - TABLE DES MATIRES


Ce cours est ddi aux tudiants de 1re anne de l'Enseirb spcialit informatique. Son intitul "Initiation l'algorithmique" est d'un certain point de vue un contresens. Tous les tudiants de l'Enseirb bnficient d'une solide culture mathmatique et ont donc ncessairement de larges connaissances en algorithme. En effet, la quasi totalit des objets mathmatiques qu'ils ont rencontr depuis leur plus tendre ge ont t dfinis de faon calculatoire. L'objet de ce cours est donc de s'appuyer sur ces connaissances et ce qu'elles reclent d'intuition pour prsenter diffrentes mthodes gnrales pour fournir un problme une ou plusieurs solutions algorithmiques. Nous insisterons sur la ncessit pour rsoudre un problme de le dcouper en sous-problmes auxiliaires, de rsoudre ainsi le premier problme avant mme d'avoir rsolu ces problmes auxiliaires. Cette approche descendante que nous suggre Descartes (Chapitre 1) est prsente dans le Chapitre 3. Ce principe universel rappel, nous prsenterons des mthodes de rsolution de problmes qui ont pour nom l'approche "Diviser pour Rgner". la Programmation Dynamique. l'approche gloutonne.

Tout au long de ce cous, nous insisterons sur diffrentes qualits attendues des algorithmes crits 1 2 3 la correction naturellement qui assure que l'algorithme rpond bien au problme. la simplicit d'criture qui met en valeur notamment les diffrentes tapes de calcul en fournissant une vision structure et donc simple de l'algorithme. la faible consommation de deux ressources que sont le temps et l'espace. En d'autres termes, nous valuerons la complexit en temps et en espace de ces algorithmes.

Les deux derniers principes sont trs souvent contradictoires. Un algorithme trs rapide en temps s'crit de faon plus complexe. Cette opposition apparat dans l'criture rcursive dans de trs nombreux cas, celle-ci offre une dfinition trs simple mais utilise des ressources en espace non constant, alors qu'une version itrative plus complique dfinir utilise moins d'espace. Pour cette raison, nous aurons soin pour certains problmes d'crire plusieurs solutions algorithmiques, chacune ayant une qualit singulire. La rsolution du problme Tri conclura ce cours en illustrant l'intrt des mthodes prsentes plus haut. Ce cours n'est pas un cours d'algorithmique et structures de donnes. Il ne contiendra pas notamment les classiques notions de Pile, Liste et File, d'arbres ou de graphes, ni leurs dfinitions, ni fortiori leurs implmentations. Les exemples de problmes concernant auant que faire ce peut des objets simples comme les boolens, les entiers ou des objets dj trs familiers tous les tudiants comme les tableaux ou matrices. Nous pouvons conseiller quelques documents 1. Ce document accessible http://www enseirb fr/lapoire/lereAnnee/InitiationAlgorithme/Cours/. Nous rappelons que ce document est disponible sous forme papier. Il n'est donc pas utile de l'imprimer. Les remarques, corrections ventuelles sont les bienvenues et sont sollicites 1apoireenseirb f r. 2. "Introduction l'algorithmique" de Cormen and Co. Collection Dunod. Cet ouvrage est prsent la bibliothque de l'Enseirb. Il est complet, long( plus de 1000 pages) et couvre l'ensemble des notions vues dans ce cours dans de nombreux autres cours d'Informatique de l'Enseirb. Les chapitres concerns par ce cours sont les chapitres 1, 2, 3, 4, 6, 7, 15, 16 et 28.

-4-

Initiation l'algorithmique par Denis Lapoire

II - Chapitre 1 Discours de la Mthode(extraits)


"Au lieu de ce grand nombre de prceptes dont la logique est compose, je crus que j'aurois assez des quatre suivants, pourvu que je prisse une ferme et constante rsolution de ne manquer pas une seule fois les observer. Le premier tait de ne recevoir jamais aucune chose pour vraie que je ne la connusse videmment tre telle; c 'est-dire, d'viter soigneusement la prcipitation et la prvention, et de ne comprendre rien de plus en mes jugements que ce qui se prsenterait si clairement et si distinctement mon esprit, que je n'eusse aucune occasion de le mettre en doute. Le second, de diviser chacune des difficults que j'examinerais, en autant de parcelles qu'il se pourrait, et qu'il serait requis pour les mieux rsoudre. Le troisime, de conduire par ordre mes penses, en commenant par les objets les plus simples et les plus aiss connatre, pour monter peu peu comme par degrs jusque la connaissance des plus composs, et supposant mme de l'ordre entre ceux qui ne se prcdent point naturellement les uns les autres. Et le dernier, de faire partout des dnombrements si entiers et des revues si gnrales, que je fusse assur de ne rien omettre. Descartes, Discours de la Mthode(1 637)

III - Chapitre 2 Quelques dfinitions et quelque syntaxe


Dans ce chapitre, nous prsentons le pourquoi d'un algorithme sa raison d'tre est de rsoudre un problme. Nous prsenterons en outre un langage de description algorithmique. Celui-ci est propre ce cours. Il a t choisi pour des raisons de simplicit et de proximit avec d'autres langages comme le langage C.

III-A - 2.1 Problmes


La raison d'tre d'un algorithme est de rsoudre un problme. La plus grande attention doit tre porte la comprhension du problme, faute de quoi l'algorithme n'a aucune chance d'tre correct. Le langage utilis pour la dfinition d'un problme est un langage scientifique utilisant pour des raisons de simplicit une langue naturelle (le franais par exemple) ou, pour lever toute ambiguiit, un langage logique. La comprhension du problme ncessite la matrise de ce langage. Un problme est une relation binaire liant deux objets. Un exemple de problme est
problme Puissance Entre : un rel x#O, un entier n Sortie : le rel

Cette relation n'est pas ncessairement fonctionnelle. comme par exemple le problme suivant problme FacteurPremier
Entre : un entier n> 1 Sortie : un facteur propre premier de n si il en existe, O sinon.

-5-

Initiation l'algorithmique par Denis Lapoire

III-B - 2.2 Types


Les objets manipuls ici sont typs. Un type est en fait un ensemble d'oprations permettant de manipuler ces objets. Le type le plus lmentaire est sans contestation possible le type boolen que l'on peut dfinir l'aide de cinq oprations 1 2 3 4 5 vrai() qui retourne le boolen vrai. faux Q qui retourne le boolen faux. A qui associe aux deux boolens vrai le boolen vrai et faux sinon. Cette opration peut se noter et. V qui associe aux deux boolens faux le boolen faux et vrai sinon. Cette opration peut se noter ou. qui associe vrai la valeur faux et inversement. Cette opration peut se noter non.

D'autres types seront utiliss, comme le type entier. Les oprations fournies seront, sauf mention contraire, les oprations arithmtiques classiques, addition, multiplication, division euclidienne, etc .... Parfois, nous nous interrogerons sur la faon optimale d'implmenter ces fonctions auquel cas, nous supposerons par exemple que seule l'addition est fournie et qu'il nous faut redfinir par exemple la multiplication. Nous fournirons alors une description dtaille de l'opration additive fournie. Sa complexit en temps dpend des hypothses (voir Section 4.3). Un autre type est le type tableau. Les oprations sur ce type permettent de 1 de construire un tableau. Il faut alors fournir sa longueur, une valeur d'initialiser chacun des lments et son premier indice (si il n'est pas fourni, on supposera qu'il s'agit de 1). Ainsi constructTab(1O) (100) (1) retourne un tableau de longueur 10 de valeurs toutes gales 100 et de premier indice 1. de calculer sa longueur. La fonction longueur retourne la longueur d'un tableau. de calculer ou de modifier la valeur d'un tableau T un indice j fourni. Nous utiliserons alors l'expression dj familire T [i].

2 3

III-C - 2.3 Algorithme


Un exemple d'algorithme rsolvant Puissance est Comme nous pouvons l'observer sur l'exemple de l'algorithme puissance, un algorithme est un texte compos de deux parties 1 2 une partie entte, appele aussi prototype. Dans l'exemple fonction puissance( x : rel ; n : entier) : rel. le corps de l'algorithme qui fournit sa dfinition. Dans l'exemple dbut fin.

-6-

Initiation l'algorithmique par Denis Lapoire

III-C-1 - 2.3.1 Entte de l'algorithme


L'entte d'un algorithme fournit 4 informations: 1 la premire est la nature de l'algorithme, fonction ou procdure; dans l'exemple : fonction. Celle-ci est prcise par le mot-clef fonction ou procdure. Pour des raisons de simplicit, nous utiliserons quasi exclusivement des fonctions qui contrairement aux procdures retournent en fin de calcul un ou plusieurs objets typs. Ainsi, le rsultat du calcul effectu devra tre retourn (instruction retourner prsente plus bas). le second est le nom de l'algorithme; dans l'exemple : puissance. Une grande importance doit tre consacr la dfinition de ce nom. Plusieurs mthodes existent quant la dfinition de ce nom. Une minimale dfinit le nom simplement partir du simple problme rsoudre (exemple : fonction puissance). On peut aussi indiquer dans le nom, la mthode utilise, voire le type des objets passes en entre ou en sortie. Ces choix sont primordiaux dans l'criture de longs programmes ncessitant l'criture d'un grand nombre de fonctions. Les exemples que nous prsenterons sont relativement simples et concis et donc ne ncessitent pas cet effort. le troisime est le nom et le type des arguments en entre; dans l'exemple ( x : rel ; n : entier). Les diffrents types sont ceux spcifis par le problme. la quatrime est le type (ou les types) de l'objet retourn par la fonction (dans l'exemple rel). Les types retourns sont ceux spcifis par le problme rsoudre.

3 4

En conclusion, except le nom de l'algorithme et le nom des arguments en entre, le prototype est entirement dpendant de la dfinition du problme rsoudre et s'crit donc sans difficult (si le problme est clairement dfini !).

III-C-2 - 2.3.2 Le corps de l'algorithme


Nous allons dfinir ici une syntaxe permettant d'crire tout algorithme. Cette syntaxe est propre ce cours. Elle n'a pas vocation permettre la compilation ou l'excution de l'algorithme sur une machine. Son ambition est de fournir selon une syntaxe simple des algorithmes simples et non ambigus qui pourront tre traduits, avec un minimum d'effort, dans un langage de programmation comme le Langage C.

III-C-3 - 2.3.3 Variable


La quasi-totalit des problmes ncessitent pour leur rsolution un espace mmoire auxiliaire sur lequel sont excuter des calculs intermdiaires. Pour grer de faon simple et lisible cette espace mmoire, on utilise des "variables".
-7-

Initiation l'algorithmique par Denis Lapoire

Ainsi, derrire toute variable, se trouve un espace mmoire dont on peut modifier le contenu. De faon plus abstraite et donc plus formelle, une variable possde plusieurs attributs 1. un identificateur. Ce nom dont elle ne change pas devra tre choisi de faon judicieuse pour rendre l'algorithme comprhensible. Naturellement, il ne peut pas tre choisi parmi les mots clefs dbut, tantque, etc. 2. un type. La variable possde sa cration un type dont elle ne peut pas changer. Notons que dans d'autres langages, d'autres choix existent. 3. une valeur. Ds sa cration, la variable possde une valeur de, naturellement, mme type. Cette valeur peut naturellement varier d'o le nom de variable. 4. une dure de vie. Dans un objectif de simplification, une variable existe uniquement au cours d'un appel de fonction et cesse la fin de cet appel de fonction, donc lors de l'excution de l'instruction retour. Exemple 1 Voici un second algorithme qui nous permettra d'illustrer comment crer une variable et comment modifier la valeur d'une variable l'aide de l'opration d'affectation +

III-C-4 - 2.3.4 valuation d'expression


Tout programme contient des expressions types. Une expression type est une expression bien forme vrifiant la syntaxe du type considre.

-8-

Initiation l'algorithmique par Denis Lapoire

Par exemple 2.j + 2 est une expression de type entier. Puisque tout moment de l'excution d'un algorithme chaque variable possde une valeur, tout moment on peut valuer une expression, c'est dire lui associer une valeur. Dans l'exemple prcdent, avant excution de T [i] <-2 + 2 ;, la variable a pour valeur 5, aussi l'valuation de l'expression 2 . + 2 fournit la valeur 12. Ces expressions peuvent naturellement tre construites partir de fonctions. Ainsi (exemplelO+20.exemplelO) est une expression de type entier construite partir de la fonction exemple 1 qui retourne chaque appel la valeur entire 10. L'valuation de (exemplelO+20.exemplelO) fournit la valeur entire 210.

III-C-5 - 2.3.5 Initialisation


Pour crer une variable, il suffit d'utiliser l'opration affectation f- et de prciser droite de ce symbole sa premire valeur. Ainsi i<-4 cre une variable de nom i, de type entier puisque 4 est de ce type et de valeur 4. Ainsi r<-4.0 cre une variable de nom r, de type rel puisque 4.0 est de ce type et de valeur 4.0. Ainsi j<-i cre une variable de nom j, de type entier puisque j est de ce type et de valeur celle de i savoir 4. Notons que les variables j et j sont distinctes, ainsi la prochaine modification de j n'entrainera pas de modification de j. En ce qui concerne le type tableau, vous pouvez utiliser un constructeur de tableau. Ainsi, T<-constructTab(10) (100) (1) cre une variable T, de nom T, de type tableau et dsignant un tableau de taille 10, lments tous gaux 100 et de premier indice 1.

III-C-6 - 2.3.6 Modification de valeurs


Une fois la variable cre. l'utilisation de l'affectation - permet de modifier la valeur de la variable. Dans le programme exemple 1, i<-5 remplace l'ancienne valeur 4 par la valeur 5. En ce qui concerne les tableaux, seules les modifications lmentaires sont autorises. Ainsi, T[i]<- j modifie la 5me case du tableau T de valeur initiale 100 par la valeur de l'expression 2.j+2 savoir 12.

III-C-7 - 2.3.7 Mise en squence


La premire possibilit pour structurer un ensemble d'instructions est leur mise en squence. La syntaxe est
dbut <instruction 1> <instruction 2> <instruction n> f in

L'excution d'une telle squence est ralise en excutant d'abord l'instruction <instruction 1>, puis l'instruction <instruction 2> jusqu' l'instruction <instruction n>.

-9-

Initiation l'algorithmique par Denis Lapoire

III-C-8 - 2.3.8 Branchement conditionnel


Une deuxime possibilit pour structurer un ensemble d'instructions est l'utilisation du branchement conditionnel si alors sinon. La syntaxe est
si <expression boolenne> alors <instruction 1> sinon <instruction 2>

L'excution d'une telle instruction consiste valuer l'expression <expression boolenne> (qui doit ncessairement tre de type boolen!) c'est dire lui associer ou le boolen vrai ou faux puis ensuite, si l'valuation fournit vrai excuter <instruction 1>, et sinon excuter <instruction 2>. Exemple 2 La fonction maximum de la figure 2.3 associe comme valeur la fonction maximum(a,b : entier) : entier

variable maxi la valeur de la variable a si l'expression a>b est vraie ou sinon la valeur de la variable b. Clairement, maxi prend pour valeur le maximum des valeurs de a et b. La fonction maximum permet bien de calculer le maximum des deux paramtres passs en entre.

III-C-9 - 2.3.9 Autres branchements conditionnels


Notons l'existence d'autres branchements conditionnels. Par exemple, si alors dont la syntaxe
si <expression boolenne> alors <instruction> est quivalent si <expression boolenne> alors <instruction 1> sinon ne rien faire

III-C-10 - 2.3.10 Boucle


Une troisime possibilit pour structurer un ensemble d'instructions est l'utilisation de la boucle tantque.

- 10 -

Initiation l'algorithmique par Denis Lapoire

La syntaxe est
tantque <expression boolenne> faire <instruction>

Une dfinition formelle de cette boucle peut tre faite en utilisant le branchement conditionnel si alors l'instruction
tantque <expression boolenne> faire <instruction> est quivalente au sous-programme (infini!) suivant si <expression boolenne> alors dbut <instruction> si <expression boolenne> alors dbut <instruction> si <expression boolenne> alors dbut <instruction> si <expression boolenne> alors dbut <instruction> ETC f in f in f in f in

Cette dfinition peut crer une certaine gne un sous-programme infini peut tre difficile concevoir. Aussi, nous illustrerons la dfinition du tantque l'aide de l'exemple suivant Exemple 3 L'excution de i +- 31. tantque (i>28) i+-i-2 <instruction suivante> consiste associer i la valeur 31 puis valuer l'expression i>28 qui fournit le boolen vrai (car 31 > 28) et donc excuter i<-i-2; la valeur de j est alors 29; valuer l'expression i>28 qui fournit le boolen vrai (car 29 > 28 est vrai) et donc excuter i<-i-2; la valeur de i est alors 27; valuer l'expression i>28 qui fournit le boolen vrai (car 27 > 28 est faux) ; l'instruction tantque est alors finie d'tre excute; on excute alors <instruction suivante> La structure de contrle tantque est trs puissante. Elle permet de mettre en squence un nombre aussi grand qu'on le souhaite d'une mme instruction, voire mme d'un nombre infini, comme le montre l'exemple suivant Exemple 4 L'excution de i +- 31. tantque (i<>28) <> signifie #

- 11 -

Initiation l'algorithmique par Denis Lapoire

i+-i-2 <instruction suivante> consiste associer i la valeur 31 puis valuer l'expression i<>28 qui fournit le boolen vrai (car 31 28 est vrai) et donc excuter i<-i-2; la valeur de i est alors 29; valuer l'expression i<>28 qui fournit le boolen vrai (car 29 28 est vrai) et donc excuter i<-i-2; la valeur de i est alors 27; valuer l'expression i<>28 qui fournit le boolen vrai (car 27 28 est vrai) et donc excuter i<-i-2; la valeur de i est alors 25; et ainsi de suite La boucle ne finira jamais d'tre excute. Nous entrons dans ce que nous appelons une "boucle infinie". Le programme dans lequel serait excute une telle instruction ne retourne aucune valeur car ne termine pas. Les programmes que vous devrez crire devront terminer. La question cruciale de la terminaison sera aborde dans le chapitre suivant.

III-C-11 - 2.3.11 Autres boucles


D'autres boucles existent. Citons en trois (cette liste n'est pas exhaustive et sera enrichie en cours ou en TD) 1. la boucle de syntaxe
faire <expr. entire> fois <instruction> Elle est quivalente indice +- <expr. entire> tantque indice > O faire dbut <instruction> indice +- indice - 1. f in

2. la boucle de syntaxe pour <variable entire> de <expr. entirel> <expr. entire2> <instruction> Elle est quivalente
<variable entire> +- <expr. entirel> tantque (<variable entire> < <expr. entire2>) faire dbut <instruction> indice +- indice + j f in

3. la boucle de syntaxe faire


<instruction>

- 12 -

Initiation l'algorithmique par Denis Lapoire

jusqu'.
<expression boolenne>

Elle est quivalente


dbut <instruction> tantque non(<expression boolenne>) faire <instruction> f in

Par leur dfinition mme. ces trois boucles n'augmentent pas la pouvoir expressif du langage algorithmique les boucles tanque suffisent. Quel est donc leur intrt? Elles permettent d'crire des algorithmes de comprhension plus simple. Proprit que nous attendons de tous les algorithmes que vous crirez.

III-C-12 - 2.3.12 Instruction retourner


L'excution de toute fonction doit se terminer par l'excution de la fonction retourner ayant pour argument un de type gal au type retourn par la fonction. Lors de l'excution de l'instruction retourner <expression>, l'expression est value, cette valeur est alors retourne, l'excution de la fonction est finie. Ainsi, la fonction
fonction add(n : entier) :entier retourner n+1.

permet de calculer l'entier qui succde l'entier n. Certaines syntaxes imposent que toute fonction ne possde qu'une instruction retourner et que celle ci soit la fin. Pour des raisons de simplicit non de syntaxe mais d'criture, nous accepterons le contraire, si cela se justifie comme dans l'exemple suivant Exemple 5 Considrons le problme qui consiste dcider si un entier n est prsent dans un tableau d'entiers
problme Recherche Entre : un entier a, un tableau d'entier T Sortie : vrai si il existe 1< i < longueur(T) tel que a=T[i] faux sinon

Une premire solution peut tre


fonction recherchel(a : entier ; T : tableau d'entiers) : boolen dbut res +- faux() pour i de 1. longueur(T) si (a = T[i]) alors res +- vrai() retourner res f in

L'algorithme recherche2 de la Figure 2.4 fournit une seconde solution; elle permet de quitter la boucle ds que l'on a trouv le bon indice et utilise pour cela une boucle tantque. Les deux solutions ont chacune un avantage la premire est de dfinition plus simple alors que la seconde est (un peu) plus rapide mais de dfinition plus complexe. Une solution aussi simple que la premire et aussi rapide que la seconde est fourni par l'algorithme recherche3 (Figure 2.5); il utilise retourner l'intrieur de la boucle tantque.

- 13 -

Initiation l'algorithmique par Denis Lapoire

Exercice 1 Ecrire un algorithme solution de Recherche obtenu partir de recherche2 en remplaant la boucle tantque par une boucle JusquA. Vous pourrez dans un premier temps rcrire l'algorithme de faon automatique en utilisant la rgle de rcriture dfinissant la boucle JusquA partir de la boucle tanque. Dans un second temps, vous modifierez l'algorithme ainsi obtenu en le rendant plus simple et plus comprhensible.

III-C-13 - 2.3.13 Appel de fonctions


Nous pouvons bien entendu utiliser une fonction dj dfinie pour en dfinir une seconde. Dans l'exemple de la Figure 2.6, la fonction tata utilise pour sa dfinition la fonction toto. Dans l'exemple de la fonction toto, en supposant que le paramtre a prenne pour valeur l'argument 10, l'tat des variables aux instants ti, t2 et t3 sera instant tlO variables existantes : a valeur de a : 10

- 14 -

Initiation l'algorithmique par Denis Lapoire

instant t20 variables existantes : a , b


valeur de a valeur de b instant t30 valeur de a valeur de b : 10 : 13 variables existantes : a , b , c : 10 : 13

Exemple 6 fonction toto(a:entier) :entier

valeur de c : 16 Remarquons ds prsent que la modification de la variable a l'intrieur de la fonction toto (instruction a <- a + 3 ;) n'a pas entrain de modification de valeur de la variable a du programme tata: l'instant t20, la variable a conserv la valeur 10 qu'elle avait l'instant tlO. Rcursivit Observons que tout ce qui n'est pas interdit tant autoris, la dfinition d'une fonction peut contenir des appels ellemme. L'exemple trop clbre du problme Factoriel admet ainsi pour solution
fonction factoriel(a:entier) :entier dbut si a = 1 alors retourner sinon retourner a factoriel (n-1) end

La comprhension de cet algorithme prsente deux difficults: 1. sa correction.

- 15 -

Initiation l'algorithmique par Denis Lapoire

Cette difficult en fait n'en est pas une. Sa correction est la consquence immdiate de la dfinition mathmatique mme de a! : a! peut tre dfini comme tant l'entier gal 1 si a = 1 et gal a (a - 1)! sinon. 2. sa complexit(en temps et en espace). Ce point plus dlicat exige de connatre prcisment le modle de calcul, c'est dire la faon dont sont grs les diffrents appels rcursifs, au sein de ce que appelons la pile d'appel. Ces diffrentes notions seront traits dans de prochains chapitres ainsi que dans d'autres cours dispenss l'Enseirb. Lire la conclusion de ce chapitre ce suj et.

III-C-14 - 2.3.14 Indentation


Afin de gagner en lisibilit, on doit utiliser les sauts de ligne et les espaces blancs de faon ce que l'criture de votre programme mette en valeur sa structure intrinsque. Ainsi, l'algorithme recherche2 crit correctement plus haut ne peut pas s'crire ainsi
fonction recherche2(n : entier ; T : tableau d'entiers) : boolen dbut res +- f aux() ; i +- 1. tant que (res=faux ET i < longueur(T)) dbut si (n = T[i]) alors res +- vrai() ; i +- i + j fin retourner res ; fin

Cette criture est formellement correcte mais est illisible un compilateur la comprendrait mais pas un humain. On autorise souvent d'utiliser cette indentation pour masquer les parenthses (dbut, fin) en effet, il y a redondance entre un texte bien indent et ces parenthses. Ainsi, l'algorithme recherche2 peut s'crire de la faon dcrite par la Figure 2.7.

Utilisez cette tolrance avec prcaution. En effet, une erreur d'indentation et votre programme est radicalement diffrent. Ainsi, le programme recherche4 (Figure 2.8) est totalement diffrent, faux et d'ailleurs ne termine pas.

- 16 -

Initiation l'algorithmique par Denis Lapoire

Exercice 2 Trouver une instance pour lequel recherche4 ne termine pas. crire avec des parenthses dbut, fin ce mme algorithme recherche4.

III-D - 2.4 Conclusion


Nous avons prsent dans ce chapitre de faon une syntaxe des programmes crire. Cette syntaxe est simple. Vous tes en mesure de "comprendre" (au sens syntaxique) n'importe quel programme. Malheureusement, contrairement une langue trangre o la comprhension d'une syntaxe et d'un dictionnaire caractrise une bonne matrise de la langue, cette connaissance l n'est qu'un prambule votre initiation aux algorithmes. Nous verrons dans les prochains chapitres quelques mthodes trs gnrales pouvant permettre de trouver la solution algorithmique un problme donn (Chapitres 3, 5, 6 et 7). Nous verrons aussi comment crire des algorithmes en respectant les proprits essentielles d'un bon algorithme sa lisibilit Obtenu notamment par de simples rgles d'indentation, par des choix de noms de variables et de sous-fonctions, par une bonne dcomposition du problme en sous-problmes auxiliaires. sa correction La notion de correction sera dfinie dans le Chapitre 3. Nous veillerons naturellement ce que l'ensemble des algorithmes prsents et tudis soient corrects. Cependant les outils permettant de prouver formellement la correction d'un algorithme seront prsents dans les cours Analyse d'Algorithmes et Structures Arborescentes. Naturellement ces outils seront partiellement en TD. sa faible complexit en temps et/ou en espace Les Chapitres 4,5,6 et 7 aborderont ces notions.

- 17 -

Initiation l'algorithmique par Denis Lapoire

IV - Chapitre 3 Problmes
Rsoudre un problme consiste crire un algorithme. Nous dirons qu'un algorithme A rsout un problme P si pour toute instance (entre) x de P, la sortie y retourne par l'algorithme A, lorsque celui-ci termine, est une des sorties spcifies par le problme P. L'algorithme prsente ncessairement diffrentes tapes de calcul. Ces tapes peuvent se situer des niveaux diffrents. Il est alors important de savoir hirarchiser ces niveaux. Ainsi, par exemple, si au cours d'un algorithme il faut calculer le maximum de deux entiers a et b et affecter le rsultat une variable c, il est incongru d'crire le code
si a < b c -b sinon c - a

Il faut crire c <- maximum(a,b), quitte redfinir la fonction maximum. On gagne en lisibilit, on vite d'ventuels erreurs, mais surtout on n'encombre pas la dfinition de l'algorithme gnral de calculs subalternes. Ainsi, pour rsoudre un problme, on crit pas une seule fonction, mais de fait une fonction gnrale qui fait ellemme appel d'autres fonctions auxiliaires, solutions elles-mmes d'autres problmes auxiliaires.

IV-A - 3.1 Un premier exemple


Si l'on souhaite rsoudre le problme suivant
problme lmentMax Entre : un tableau T d'entiers non vide Sortie : l'entier maximum des entiers de T

l'algorithme
fonction lmentMaxl(T:tableau d'entiers) :entier res +- T[1] pour i de 2 longueur(T) si T[i] > res res +- T[i] retourner res

nous prfrerons l'algorithme suivant


fonction lmentMax2(T:tableau d'entiers) :entier res +- T[1] pour i de 2 longueur(T) res +- maximum(res,T[i]) retourner res

Il nous faudra alors prciser le problme rsolu par maximum savoir


problme Maximum Entre : deux entiers a et b Sortie : le maximum de a et b

et ventuellement rappeler la dfinition d'un algorithme rsolvant ce problme. Cette dfinition a dj t faite et est donc dsormais inutile.

- 18 -

Initiation l'algorithmique par Denis Lapoire

IV-B - 3.2 Un second exemple


Considrons le problme suivant
problme FacteurProprePremier Entre : un entier a> 1 Sortie : un facteur propre premier de a si il en existe, O sinon.

Une premire solution consisterait crire


fonction facteurProprePremierO(a: entier) : entier pour i de 1. a-1. faire si estDiviseur(i,a) alors retourner i retourner O

Cette solution bien que concise est une mauvaise solution. Elle ne met pas en valeur les diffrents sous-problmes associs celui-ci et prsente un algorithme trs mauvais car trs lent nous verrons dans le chapitre que cet algorithme est en fait exponentiel. Cette solution n'tant pas dcompose l'aide de fonctions auxiliaires, vous ne savez pas rcrire cet algorithme si ce n'est en le rcrivant totalement :dit autrement, cet algorithme est prendre ou jeter entirement. Nous ne le conserverons donc pas. Avant de rsoudre un problme, il faut comprendre celui-ci.

IV-C - 3.3 Comparaison de problmes


Dans cette section, nous montrons comment extraire d'un problme des sous- problmes plus simples. Ce qui permet d'une part de progresser d'un problme plus simple vers des problmes plus difficiles et d'autre part de dcomposer un problme en un ensemble quivalent de sous-problmes. Il s'agit d'appliquer humblement les principes second et troisime du Discours de la Mthode (voir Chapitre 1). Si vous rencontrez des difficults rsoudre un problme, extrayez-en un plus simple et essayez de le rsoudre. Nous dirons qu'un problme P est aussi simple d'un point de vue logique qu'un problme Q, si tout algorithme solution de Q est une solution de P. Si il est diffrent, il sera dit plus simple. Si l'on vous demande de rsoudre algorithmiquement un problme Q, pensez en en extraire un problme plus simple P. En effet, la rsolution de P est un passage oblig pour la rsolution de Q toute solution de Q tant une solution de P, si vous ne savez pas rsoudre P, vous ne savez pas rsoudre non plus P!

IV-C-1 - 3.3.1 Augmenter les contraintes en entre


Une faon d'en extraire un plus simple est de limiter les instances. Ainsi, par exemple, le problme FacteurProprePremier induit comme nouveau problme si l'on se rduit aux entiers nombres non premiers
problme FacteurPremierRestreint Entre : un entier a> 1 qui n'est pas premier Sortie : un facteur premier de a

IV-C-2 - 3.3.2 Diminuer les contraintes en sortie


Une seconde faon de simplifier un problme est au lieu de restreindre les entres, de relcher les sorties c'est dire de rduire les contraintes portant sur les sorties.
- 19 -

Initiation l'algorithmique par Denis Lapoire

Ainsi, un problme plus simple car extrait de FacteurPremierRestreint en remplant "facteur propre premier" par "facteur propre" est
problme FacteurPropre Entre : un entier a> 1 qui n'est pas premier Sortie : un facteur propre de a

En outre, un problme plus simple que FacteurProprePremier est obtenu en remplaant "un facteur propre premier de n" par un entier > 1. On obtient clairement le problme suivant
problme EstComposite Entre : un entier a> 1 Sortie : un entier > O si il existe un facteur propre premier de a O sinon.

Ce dernier problme est appel EstComposite car il est trs proche du problme qui dcide si un entier est composite
problme EstComposite Entre : un entier a> 1 Sortie : vrai si il existe un facteur propre premier de a faux sinon.

Rappelons qu'un entier est premier si il admet exactement deux diviseurs 1 et lui-mme et est composite sinon. Il est facile d'observer sur cet exemple, que toute solution algorithmique facteurProprePremier de FacteurProprePremier est une solution de chacun des problmes 1 2 3 FacteurPremierRestreint FacteurPropre EstComposite

IV-C-3 - 3.3.3 Dcomposition en un ensemble quivalent de sous- problmes


Dans la section prcdente, nous avions montr que les problmes FacteurPremierRestreint et EstComposite sont plus simples que FacteurProprePremier. L'algorithme suivant prouve que FacteurProprePremier se dcompose exactement en deux premiers problmes.
fonction facteurProprePremier(a: entier) : entier si estComposite (a) retourner facteurPremierRestreint (a) sinon retourner O

Observons que si l'on sait rsoudre FacteurPropre, on sait rsoudre FacteurPremierRestreint la condition que l'on sache rsoudre le problme EstComposite.
fonction facteurPremierRestreint(a:entier) :entier faire a +- f acteurPropre(a) jusqu' non(estComposite(a) retourner a

Conclusion mthodologique

- 20 -

Initiation l'algorithmique par Denis Lapoire

Cet exemple illustre qu'un problme initial FacteurProprePremier peut se dcomposer en deux problmes FacteurPropre et EstComposite. Pour rsoudre le premier il est ncessaire et mme suffisant de rsoudre les deux autres. En introduction, nous avions indiqu que la solution facteurProprePremierO tait une mauvaise solution car trs lente il peut utiliser jusqu' instructions lmentaires. Est-ce que l'algorithme facteurProprePremier est meilleur? Tout dpend bien entendu des fonctions auxiliaires estComposite et f acteurPropre. De premires solutions immdiates seraient
fonction estComposite(a:entier) :boolen pour i de 2 a-1. faire si estDiviseur(i,a) retourner faux retourner vrai fonction facteurPropre(a:entier) :entier pour i de 2 a-1. faire si estDiviseur(i,a) retourner i

Ces solutions ncessitent chacune oprations; si elles taient retenues, entraineraient un nombre d'oprations pour f acteurProprePremier gal 2 Si l'on interroge la communaut scientifique, nous obtenons deux rponses 1. la premire rponse est une bonne nouvelle le problme EstComposite peut tre rsolu l'aide d'un algorithme estComposite ncessitant (log(a))'2 oprations lmentaires. Cet algorithme, dcouvert rcemment, est trop compliqu pour tre prsent dans ce cours. 2. la deuxime rponse est une mauvaise nouvelle on ne sait pas rsoudre facteurPropre avec des algorithmes rellement plus efficaces que facteurPropre. Sur un exemple, nous avons dcompos un problme FacteurProprePremier en deux problmes EstComposite et FacteurPropre, nous avons montr que la rsolution du premier problme tait quivalent la rsolution des deux autres problmes. Ayant appris que le deuxime problme pouvait tre rsolu "rapidement", nous en avons dduit que la difficult du premier rsidait dans la difficult du troisime. Cette approche de dcomposition doit tre privilgie systmatiquement. Elle met en valeur des liens existant avec d'autres problmes, ventuellement dj tudis ou dj rsolus. En outre, elle permet de rpartir le travail auprs de diffrentes quipes. Chacune ayant pour objectif de rsoudre l'un des sous problmes. dans le temps. Si l'avenir, une meilleure solution apparaissait en ce qui concerne FacteurPropre, elle pourrait tre introduite immdiatement dans votre algorithme.

V - Chapitre 4 Terminaison et complexits


un mme problme, diffrentes solutions algorithmiques peuvent tre proposes. Nous avons vu dans le chapitre prcdent l'existence d'algorithmes qui ne terminent pas, c'est dire qui sur certaines entres peuvent ne jamais retourner de rsultat car entrant dans des boucles infinies. La premire qualit attendue d'un algorithme est bien sr sa terminaison.

- 21 -

Initiation l'algorithmique par Denis Lapoire

Un second critre permet de les comparer et ainsi d'en distinguer de meilleures que d'autres. Ce critre est la faible utilisation de deux ressources le temps l'espace.

V-A - 4.1 Terminaison


L'une des qualits attendus d'un programme est qu'il termine, c'est dire qu'il n'admette aucune instance pour laquelle l'excution rentre dans une boucle infinie. On touche ici l'un des problmes difficiles en informatique. Par exemple, la communaut scientifique n'a pas russi prouver que l'algorithme suivant
fonction syracuse(a:entier) : mot tantque a<>1. faire si a est pair alors a sinon a retourner ''fini''

terminait sur chaque entre n. Nous avons bien-sr excut l'algorithme sur un grand nombre d'entiers et observ que le calcul terminait chaque fois. Mais nous n'avons aucune certitude en ce qui concerne tous les entiers. Cet exemple traduit le fait que nous n'avons pas de mthode pour dcider si un algorithme termine. Pire, nous avons prouv qu'il n'existe pas de mthode universelle pour dcider si un algorithme termine. En clair, le problme de la terminaison
Terminaison Entre : un algorithme A Sortie : le boolen indiquant si A termine ou non

est un problme indcidable, c'est dire incalculable on prouve qu'il n'existe aucun algorithme le rsolvant. Exemple 7 Il existe d'autres exemples de problmes indcidables. L'un des plus clbres est le dixime problme de Hilbert, qui s'interrogeait en 1900 sur l'existence d'un algorithme dcidant l'existence d'une racine entire pour une quation polynomiale coefficients entiers. Nous savons aujourd'hui qu'il n'en existe pas ce problme est indcidable. Ne prenez pas prtexte de l'indcidabilit de la terminaison, pour produire des algorithmes ne terminant pas. Avec un minimum de mthodologie, il est possible lorsque vous crivez un algorithme de vous assurer de faon formelle qu'il termine.

V-B - 4.2 Complexit


Nous l'avons dj dit, un grand nombre de problmes fournissent dans la dfinition mathmatique des objets mentionns une solution algorithmique.
problme Puissance Entre : un rel x, un entier a Sortie : le rel Xa

- 22 -

Initiation l'algorithmique par Denis Lapoire

Si on utilise la dfinition de vue en troisime ou en quatrime, savoir x multipli par lui mme n fois, on obtient l'algorithme suivant
fonction puissancel(x:rel ; a : entier) : rel res +- 1. faire a fois res +- res x retourner res

Si vous prfrez la relation rcursive apprise en seconde Xa est gal 1 si a vaut O et x x' sinon. Vous en dduisez l'algorithme suivant
fonction puissance2(x:rel ; a : entier) : rel si (a0) alors res +- 1. sinon res +- xopuissance2(x,a-1) retourner res

Ces deux algorithmes sont tous deux corrects mais ne sont pas quivalents, le second utilisant davantage de ressources espace que le premier. Les deux ressources que nous considrerons ici sont le temps et l'espace.

V-C - 4.3 Complexit d'une entre


Avant de dfinir ce qu'est la complexit d'un algorithme, il nous faut dfinir la complexit d'une entre (instance) manipule par cet algorithme. Dfinition 1 La complexit (ou taille) d'une entre est le nombre d'octets ncessaires sa reprsentation. Comme nous le verrons par la suite, la complexit d'un objet (entre, algorithme ou problme) est dfinie une constante multiplicative prs.

V-C-1 - 4.3.1 Complexit d'un boolen


Ainsi, par exemple, un boolen ncessite pour sa reprsentation un octet (en fait un bit suffit). Nous dirons qu'il est de complexit ou taille constante. Complexit d'une matrice de boolen Une matrice n lignes, m colonnes de boolens est de complexit n m.

V-C-2 - 4.3.2 Complexit d'un entier


Trois hypothses apparaissent 1 La premire faon de reprsenter un entier est de lui allouer un nombre d'octets fixe. Ce choix ralis dans le langage de programmation C (un octet pour le type char, 4 octets pour le type int) a une limite il ne permet de reprsenter que des entiers en nombre fini. Un entier positif reprsent sur 4 octets peut prendre au plus 248 valeurs possibles les entiers sur 4 octets dcrivent l'intervalle [0, 232 - 1]. Sous cette hypothse, la complexit d'un entier est constante. La seconde faon de reprsenter un entier n est de lui allouer autant d'octets que ncessite sa reprsentation, savoir log2 (n + 1)1 (que nous noterons log(ri)). Cette reprsentation est ncessaire quand les entiers utiliss peuvent prendre des valeurs rellement trs grandes c'est le cas d'applications cryptologiques qui manipulent des entiers reprsents sur des centaines de bits.

- 23 -

Initiation l'algorithmique par Denis Lapoire

Pour des raisons pdagogiques et de simplicit, nous supposerons souvent un type entier pouvant prendre n'importe quelle grande valeur et dote d'oprations comme l'addition se ralisant en temps constant. Ce choix est un choix pdagogique mais n'admet aucune implmentation machine concrte.

V-C-3 - 4.3.3 Complexit d'une matrice d'entiers


Quand nous considrerons une matrice d'entiers n lignes m colonnes, nous supposerons que ceux-ci sont de taille constante. Ainsi, la complexit de la matrice est considre gale n m.

V-D - 4.4 Complexit d'un algorithme


Un algorithme est un objet qui partir de toute entre permet d'excuter des instructions en consommant deux ressources 1 2 du temps. Le temps sera valu en considrant le nombre d'instructions lmentaires devant tre excutes une instruction est lmentaire si elle peut tre excute en un temps fixe. de l'espace. L'espace est le noinbie d'octets utilis pal l'excution de l'algorithme. Il ne tient pas compte de l'espace utilis par les objets fournis en entre.

V-D-1 - 4.4.1 Instruction lmentaire


Le caractre lmentaire d'une instruction dpend des hypothses initiales. Ainsi, si l'on dcide de manipuler des entiers taille fixe (sur 4 octets par exemple), l'addition d'entiers (ainsi d'ailleurs que toutes les oprations) doit tre considre comme lmentaire. l'oppos si l'on considre des entiers pouvant tre de grande taille (plusieurs centaines d'octets et davantage), l'addition ne peut pas tre considre comme lmentaire car elle ncessite autant de manipulation de bits qu'il y en a de prsent.

V-D-2 - 4.4.2 Espace utilise par l'algorithme


Dans les algorithmes itratifs, l'espace utilis peut se rsumer celui ncessaire pour reprsenter les nouvelles variables utilises.
fonction factlter(a:entier) :entier res f- 1. tantque (a>1) faire res +- res a a f- a - 1. retourner res

Ainsi la complexit en espace de cet algorithme est constant. La complexit en temps est (un multiple de) n Dans les algorithmes rcursifs, il faut considrer en outre l'espace requis pour grer l'ensemble des appels rcursifs. Cette gestion est organise au travers de ce que l'on appelle une pile d'appel dont la taille est gal au nombre d'appels rcursifs. Ainsi, par exemple l'algorithme
fonction factRec(a:entier) :entier si a = O retourner 1. sinon retourner a factRec(a-1)

- 24 -

Initiation l'algorithmique par Denis Lapoire

ncessite une pile d'appel de hauteur n. En supposant que la multiplication soit lmentaire (en temps constant), la complexit en espace est un multiple de n ainsi que celle en temps.

V-D-3 - 4.4.3 Complexit en temps dans le pire des cas


La complexit en temps dans le pire des cas d'un algorithme est la fonction qui tout entier n associe le nombre d'instructions lmentaires maximal excutes par A sur des entres de complexit n. Ainsi, l'algorithme fonction decalage(a:entier) :entier
si a = O alors retourner O tant que estPair(a) faire aretourner a

qui consiste supprimer les bits nuls de poids faible a une complexit en temps (si l'on suppose l'valuation de lmentaire, ce qui est toujours le cas) 1 2 constante pour tout entier impair. gale log(a) pour toute puissance de 2.

Ainsi, sa complexit en temps dans le pire des cas est log(a). Quand nous voquerons la complexit d'un algorithme, nous considrerons la complexit dans le pire des cas. Cependant il en existe d'autres la complexit en moyenne et celle dans la meilleur des cas.

V-D-4 - 4.4.4 Complexit en temps en moyenne


La dfinition diffre de celle dans le pire des cas en considrant non le nombre maximal d'instructions lmentaires mais la moyenne du nombre d'instructions lmentaires sur l'ensemble des entres de taille n. Calculer en moyenne est un exercice souvent plus dlicat que dans le pire des cas. Dans le cas de l'algorithme decalage, cette complexit en moyenne est constante. En mesurant le nombre d'excutions de a<-a/2, on observe sur les entiers de taille 3 (reprsent ci-dessous en binaire)
001 010 011 100 101 110 111 : : : : : : : nbre nbre nbre nbre nbre nbre nbre d'instruction d'instruction d'instruction d'instruction d'instruction d'instruction d'instruction O 1 O 2 O 1 O

Ainsi, le nombre moyens d'excutions de est sur des entiers de taille 3 gal 4/7 Exercice 3 Prouver que la complexit en moyenne de decalage est constant.

V-D-5 - 4.4.5 Complexit en temps dans le meilleur des cas


La dfinition diffre de celle dans le pire des cas en considrant non le nombre maximal d'instructions lmentaires mais le nombre minimal d'instructions lmentaires sur l'ensemble des entres de taille n. Dans l'exemple de decalage, le meilleur des cas est naturellement atteint par les entiers impairs. Ainsi, la complexit en temps dans le meilleur des cas de decalage est constante.

- 25 -

Initiation l'algorithmique par Denis Lapoire

V-D-6 - 4.4.6 Complexit en espace


Pour dfinir la complexit en espace, il suffit de remplacer le terme "nombre d'instructions lmentaires excutes par A" par "nombre d'octets utilises lors de l'excution de A". A l'image de la complexit en temps, il existe notamment trois complexits en espace 1 2 3 dans le pire des cas. en moyenne dans le meilleur des cas.

V-E - 4.5 Complexit d'un problme


Une ide naturelle est d'valuer la complexit en temps d'un problme ( de mme pour l'espace). Puisque un problme admet plusieurs solutions algorithmiques, on peut les comparer sous le critre de leur complexit en temps et considrer la plus faible que nous dfinissons comme la complexit du problme.

V-E-1 - 4.5.1 Compromis espace-temps


Il n'existe pas parfois de meilleur algorithme. Nous verrons plus loin, qu'un mme problme ayant en entre des entres de taille n peut par exemple admettre une solution algorithmique de complexit en temps dans le pire des cas en n2 et une complexit en espace constante. une solution algorithmique de complexit en temps dans le pire des cas en n et une complexit en espace n. Ces deux solutions tant incomparables, l'une ne peut tre considre comme meilleure que l'autre.

V-F - 4.6 Notations et simplifications


Le calcul des complexits est "complexe". Pour les mmes raisons qu'en ce qui concerne la terminaison, il n'existe pas de mthode gnrale (ou algorithme) pour calculer la complexit d'un algorithme et encore moins celle d'un problme. Nous montrerons comment valuer la fonction complexit d'un algorithme en valuant non pas prcisment cette fonction mais la classe laquelle elle appartient.

V-F-1 - 4.6.1 une constante multiplicative prs: notation e


Les fonctions complexit que nous considrons ds prsent sont supposes valeurs entires strictement positives. Supposons que nous utilisions des entiers manipuls au travers d'additions et de multiplications considres comme instructions lmentaires. Supposons que nous ayons deux algorithmes. Le premier sur une entre de taille n provoque 10 n additions et n multiplications. Le second n additions et 2on multiplications. Le premier a pour complexit en temps n F-* 11on. Le second n -* 3 n. Lequel est optimal? En fait tout dpend des complexits relles de l'addition et de la multiplication, c'est dire du nombre de cycles d'horloges ncessit par le processeur pour additionner et multiplier deux entiers. Deux stratgies s'offrent nous:

- 26 -

Initiation l'algorithmique par Denis Lapoire

ou on comptabilise pour chacune des oprations le nombre d'excutions. On obtient alors tant de comparaisons, tant d'affectations, tant d'additions, tant de multiplications. Cette prcision est parfois ncessaire dans l'tude d'algorithmes embarques ou temps rel mais est coteuse. ou on considre toutes ces oprations lmentaires comme quivalentes. C'est le choix que nous ferons. En consquence de quoi, il est absurde de prfrernF-*3onnF-* 11on.

En consquence de quoi, deux fonctions f et g gales une constante multiplicative prs devront tre considres comme quivalentes. La consquence de ceci, deux fonctions f et g pour lesquelles il existe des rels 0< et 0< i3 tels que: Vn.f(n) <g(n) <.f(n) et dont tels que g(n) < f(n) < g(n) devront tre considres comme quivalentes. Consquence de ce choix, deux simplifications interviennent une constante additive prs Soit f : N* -* N* une fonction et k un entier. La fonction k + f vrifie 1/k+1. k + f < f < k + f. Donc ces deux fonctions seront considres comme quivalentes. Comportement asymptotique Soit f : -* N* une fonction et N un entier. Soit g la fonction qui tout entier n E [1, N] associe 1 et tout autre entier associe f(n). Soit M := max[l,N] f(i). Il est facile d'observer que Vng(n) <f(n) <M g(n) En d'autres termes, deux fonctions tant gales asymptotiquement doivent tre considres comme quivalentes. Notation e Soit f N* -* N* une fonction. Nous noterons C(f) l'ensemble des fonctions g N* -* N* telles qu'il existe un entier N, deux rels et 3 tels que pour tout entier n > N on ait .f(n) <g(n) <.f(n) Du fait que f E e(g) induit une relation d'quivalence (Exercice 5). Pour cette raison, la notation f E C(g) est remplace par la notation f = Exercice 4 Dmontrer pour toutes fonctions f, g N* -* N* et tout rel > O 1 2 e(.f)=e(f) C(f+g) = C(max(f,g))

Exercice 5 Dmontrer que la relation g E C(f) induit une relation d'quivalence (rflexive, symtrique, transitive), c'est dire que pour toute fonction f, g et h on a: 1 2 3 fEe(f). f E C(g) entraine g E e(f). f E e(g) et g E (h) entraine f E e(h).

- 27 -

Initiation l'algorithmique par Denis Lapoire

V-F-2 - 4.6.2 Des fonctions talons


Certaines fonctions N* -* N* servent d'talons et fournissent une hirarchie simple de cet ensemble indnombrable de classes. Pour des raisons de simplicit, les fonctions sont notes plus simplement ainsi la fonction n -* n2 est note plus simplement n2. Quelques exemple des fonction 1 2 3 4 5 6 7 8 la fonction 1 dite constante. la fonction logarithmique log(n). la fonction linaire n. la fonction n logn. les fonctions polynomiales n, n2, ..., nk avec k fix. des fonctions superpolynomiales comme 2". la fonction exponentielle 2. des fonction superexponentielles telles que fl, 22.

Les algorithmes que nous souhaitons faire excuter sur machine doivent tre de complexit en temps et en espace au pire polynomiale et ce selon une petite puissance (<= 4) un algorithme ncessitant 2 oprations lmentaires ncessite dans le cas o n = 10000 (par exemple une petite matrice carre de taille 100.100) un temps qui se compte en milliard d'annes! Exercice 6 Considrant qu'une opration lmentaire se fasse en 10 seconde (un milliardime de seconde), rappelant qu'une anne comporte peu prs 3.1O seconde. Calculer le temps ncessaire l'excution d'un algorithme sur une entre de taille 100, 1000 ou 10000 de complexit 1 2 3 4 5 6 n, n2, n6, n'00 2, 22h.

V-F-3 - 4.6.3 Simple majoration : notation O


Considrons la fonction
fonction toto(n : entier): entier i - n tantque i > O faire si testlnconnu(i) alors retourner i i +- i-1 retourner i

Supposons que testlncorinu se fasse en temps constant. Que peut-on dire de la complexit en temps (dans le pire des cas) de cet algorithme? Tout dpend du test que ralise testlncorinu. La complexit en temps de toto est, par exemple, 1 2 3 e(1) si testlnconnu teste la parit. e(log(n)) si testlnconnu teste la primalit la proportion de nombres premiers est e(n) si testlnconnu teste le fait d'tre puissance de 2.

Dans des situations comparables du fait de notre incapacit valuer finement la complexit, nous nous contenterons de majorer la fonction complexit. Dans l'exemple de la fonction toto, nous dirons que sa complexit en temps (dans le pire des cas) appartient la classe 0(n), c'est dire que sa fonction complexit temps est majore ( une constante multiplicative prs) par la fonction n F-* n.

- 28 -

Initiation l'algorithmique par Denis Lapoire

Ainsi, pour toute fonction f N* -* N* la classe 0(f) est l'ensemble des fonctions g telles qu'il existe un entier N et un rel > O tels que pour tout entier n > N on ait g(n) <.f(n) Pour des raisons de simplicit et de similarit avec la notation g = l'appartenance g E 0(f) est not g = 0(f). A titre d'exercice, quelques petites proprits Exercice 7 Dmontrer pour toutes fonctions f, g : N* -* N* et tout rel > O 1 2 3 0(.f)=0(f). 0(f + g) = 0(max(f, g)). (f) c 0(f).

Exercice 8 Dmontrer pour toutes fonctions f, g: N* -* N* 1 2 3 f=e(g)e(f)=e(g). f=0(g)0(f)C0(g). f=0(g)0(f)=0(g).

0 induit une relation d'ordre et non d'quivalence Observons que si n E 0(n2) (not n = 0(n2)), nous avons n2 0(n) (not n2 0(n)). La relation induite par 0 n'est pas symtrique, elle est simplement d'ordre Exercice 9 Dmontrer que la relation g E 0(f) induit une relation d'ordre large (rflexive, transitive), c'est dire que pour toute fonction f, g et h on a 1 2 fE0(f). f E 0(g) et g E 0(h) entraine f E 0(h).

V-F-4 - 4.6.4 Quelques rgles d'valuation de complexit


Pour chacun des exercices suivants, et pour chacun des entiers j E [1, 4], nous notons #fi la complexit en temps dans le pire des cas de la fonction fi.

V-F-5 - 4.6.5 Mise en squence


Exercice 10 Considrer l'algorithme suivant
fonction fl(i : entier ):entier i +- f2(i) j +- f3(i) retourner j + j

Dmontrer que 1 2 #fl = O(#f2 + #f3). #fl = e(#f2 + #f3).

Exercice 11 Considrer l'algorithme suivant


fonction fl(i : entier ):entier

- 29 -

Initiation l'algorithmique par Denis Lapoire

j +- f2(i) retourner f 3(i)

Dmontrer que 1 #fl O(#f2 + #f3) et donc #fl e(#f2 + #f3). Vous considrez des entiers de taille (complexit non constante). Vous choisirez une fonction f2 qui augmente significativement la taille de i par exemple une fonction exponentielle. Exprimer selon une notation O la fonction #f 1 en fonction de #f 2, #f 3 et f2. La fonction f2 sera suppose croissante.

V-F-6 - 4.6.6 Branchement conditionnel


Exercice 12 Considrer l'algorithme suivant
fonction fl(n:entier) :entier si f2(n) alors retourner f 3(n) sinon retourner f 4(n)

Dmontrer que 1 2 #fl = O(#f2 + #f3 + #f4). #f 1 = e(#f2 + #f 3 + #f4) n'est pas toujours vrai. Fournir un exemple.

V-G - 4.7 Un peu de vocabulaire


Quand on prcise la complexit d'un algorithme ou d'un problme, il faut dfinir en fonction de quelle quantit celleci est exprime. Nous pouvons employer l'expression "tel algorithme est de complexit linaire". A dfaut de toute prcision, ceci signifie linaire en fonction de la complexit (la taille) de l'entre X.

V-G-1 - 4.7.1 Un algorithme linaire


Considrons le problme de la comparaison de deux matrices carres de mme taille
fonction gal(A,B: matrice): boolen 1 +- nbColonnes(A) pour i de 1. 1 faire pour j de 1. 1 faire si A[i,j] B[i,j] alors retourner faux Q retourner vraiQ;

Cet algorithme est de complexit en temps e(12) quadratique en fonction de 1 mais doit tre considr comme un simple algorithme linaire (en la taille des entres et B gale n = 12) qui compare bit bit les reprsentations machines des objets. La fonction complexit est en fait e(n).

V-G-2 - 4.7.2 Un algorithme exponentiel


Considrons l'algorithme suivant.
fonction factlter(k:entier) :entier res +- 1. tantque (k>1) faire res +- res k

- 30 -

Initiation l'algorithmique par Denis Lapoire

k - k - 1. retourner res

Supposons que le produit de deux entiers est de complexit constante. Cet algorithme est de complexit en temps (k) linaire en fonction de l'entre k mais doit tre considr comme exponentiel (en la taille de l'entre k gale n = log2(k)). La fonction complexit est en fait n -* 2. Exercice 13 Qualifier chacune des complexit en temps et en espace de l'algorithme d'addition de deux matrices carres. S'agit t- il de complexit constante? logarithmique? linaire? quadratique? exponentielle? autre? Mme question pour le produit de deux matrices carres? Exercice 14 Considrons l'un des premiers algorithmes que vous excutiez dans votre jeune ge (l'entier est fourni par l'enseignant la machine c'est vous!) procdure punition(k: entier) pour i de 1. k faire crire (''J'apprendrais mes lecons'') Mme question que l'exercice prcdent.

V-H - 4.8 tude du problme de puissance


Considrons le problme de puissance d'un lment x selon une puissance k. Nous supposerons ici que toute multiplication est une instruction lmentaire (complexit en temps et en espace constante).
problme Puissance Entre : un lment x, un entier k Sortie :

Un premier algorithme est


fonction puissancel(x:lment ; k : entier) : lment res +- 1. faire k fois res +- res x retourner res

Les complexits dans le pire des cas sont 1 2 (k) en temps. e(1) en espace.

Un second algorithme est


fonction puissance2(x:lment ; k : entier) : lment si (k=O) alors retourner 1. sinon retourner x.puissance2(x,k-1)

Les complexits dans le pire des cas sont 1 2 (k) en temps. (k) en espace d la pile d'appel.

Un troisime algorithme rcursif utilisant la proprit x2k = (x2)k est


fonction puissance3(x:lment ; k : entier) : lment si (k=O) alors retourner 1. sinon si estPair(k) retourner puissance2(xox,k/2)

- 31 -

Initiation l'algorithmique par Denis Lapoire

sinon retourner xopuissance2(xox, (k-1)/2)

Clairement chaque appel rcursif, l'argument k est divis par 2, un entier k entraine log(k) appels rcursifs successifs. Les complexits dans le pire des cas sont 1 2 (l(k)) en temps. e(log(k)) en espace d la pile d'appel.

Cet algorithme induit la version itrative suivante


fonction puissance4(x:lment ; k : entier) : lment 1 +- nombreBits(k) res +- 1. pour i de 1. 1 faire res +- res res si imeBit(k,i)=1. alors res +- x res retourner res

Dans cet algorithme. nombreBits (k) retourne le nombre de bits de la reprsentation binaire de l'entier k ( c'est dire log(n + 1)1). Par exemple nombreBits(6) vaut 3 car la reprsentation binaire de 6 est 110. imeBits(k,i) retourne le ime bit partir du bit de poids fort. Ainsi, imeBits(6,1), imeBits(6,2) et imeBits(6,3) valent respectivement 1, 1 et O. Les complexits dans le pire des cas sont 1 2 e(log(k)) en temps. e(1) en espace.

Exemple 8 Si l'on souhaite calculer puissance4(1O,6) les instructions successivement excutes sont
res+-1 res +res +res +res +res +; res=1 res res x res ; res res x res ; res res

; res = 1. res = 10 ; res 100 res 1000 ; res = 1000000

Nous voyons sur cet exemple comment partir de deux dfinitions diffrentes d'un mme objet produire deux algorithmes (algorithmes puissancel et puissance2). Ces deux algorithmes ont pour avantage leur simplicit mais non leur complexit. Ensuite, nous voyons comment traduire une proprit arithmtique en un algorithme rcursif (puissance3) dont la correction est immdiate car lie troitement cette mme proprit. L'algorithme produit est optimal en temps mais non en espace. En observant comment il organise les calculs, nous pouvons le "dercursiver" et obtenir un algorithme itratif optimal en temps et en espace (algorithme puissance4).

V-H-1 - 4.8.1 Importance des hypothses


Nous avons dmontr dans la section prcdente, que le nombre d'excutions de l'opration multiplication est gal pour puissancel, e(k). pour puis sance2, e(k). pour puissance3, e(log(k)).

- 32 -

Initiation l'algorithmique par Denis Lapoire

pour puissance4, e(log(k)).

Hypothse 1 Dans cette mme section, l'tude de la complexit repose sur le fait que 1 2 les lments sont reprsents sur un nombre constant d'octets. (et donc) que l'opration de multiplication a une complexit en temps constante.

Cette hypothse est conforme au cas par exemple de rels reprsents sur un nombre d'octets fixes (hypothses ralistes). Les complexits en temps sont alors pour puissancel, e(k). pour puis sance2, e(k). pour puissance3, e(log(k)). pour puissance4, e(log(k)). La reprsentation d'un rel x dans le langage C (type float norme IEEE 754) est normalis sous la forme d'un triplet (cv, 3, 'y) reprsent sur 4 octets vrifiant l'quation x = 3o 2 o: 1 2 3 est le signe -1 ou 1 cod sur un bit. 3 est la mantisse, une fraction relle de l'intervalle [1, 2[ code sur 23 bits. 'y est l'exposant, un entier cod sur 8 bits appartenant [-126, 127]

Cependant si vous modifiez les hypothses, si vous supposez que la complexit de la multiplication n'est pas constante mais est par exemple proportionnelle la taille de l'lment multipli y (eQtaiiie(y))) vos conclusions diffreront. Hypothse 2 Ici, nous supposons que 1 2 la complexit en temps de l'addition dpend de la complexit des lments. le produit de deux lments de mme taille conserve cette mme taille Cette hypothse est notamment vrifie dans le cas du produit de deux matrices carres ( lments de taille constante).

Les complexits en temps sont alors pour puissancel, e(-taine(x) k). pour puissance2, e(taiiie(x) k). pour puissance3, e(-taiiie(x) log(k)). pour puissance4, e(taille(x) log(k)).

Sous cette nouvelle hypothse les deux derniers algorithmes sont encore bien meilleurs que les deux premiers. Hypothse 3 Ici, nous supposons que
- 33 -

Initiation l'algorithmique par Denis Lapoire

1 2

la complexit en temps de l'addition dpend de la complexit des lments. le produit de deux lments a pour taille la somme des deux tailles. Cette hypothse est notamment vrifie dans le cas du produit de deux entiers taille variable.

Les complexits en temps sont alors pour puissancel, e(tai11e(xk)) = (k taille(x)). pour puissance2, e(tai11e(xk)) = (k taille(x)). pour puissance3, e(tai11e(xk)) = (k taille(x)). pour puissance4, e(tai11e(xk)) = (k taille(x)).

Sous cette dernire hypothse, les algorithmes ont mme complexit en temps! Exercice 15 valuer la complexit en espace des diffrents algorithmes dans chacune des deux nouvelles hypothses. Exercice 16 Expliquer pourquoi dans le cadre de l'tude de la puissance supposer des entiers de taille fixe n'a pas beaucoup d'intrt et ce contrairement aux rels (de taille fixe eux aussi). Exercice 17 Qualifier la complexit de chacun des algorithmes dans chacune des hypothses est-elle constante, linaire, polynomiale, exponentielle?

VI - Chapitre 5 Algorithmes "Diviser Pour rgner"


L'approche "Diviser Pour Rgner" (Divide and Conquer) est une mthode qui permet de rsoudre un problme en fournissant un algorithme rcursif. Cette mthode n'offre naturellement aucune garantie il n'existe pas de mthode (ou algorithme) permettant partir d'un problme d'obtenir coup sr une solution algorithmique. La structure gnrale d'un algorithme "Diviser Pour Rgner" et permettant d'associer une entre x une solution s comporte 3 parties 1 2 3 la dcomposition. Celle-ci consiste dcomposer l'entre x en a nouvelles entres xl,... ,x. a appels rcursifs. Ceux-ci consistent appliquer rcursivement la fonction sur chacune des nouvelles entres x,. . . , et retourner les a solutions 5i, la recomposition. Celle-ci consiste recomposer partir des solutions partielles s, . . , la solution s associe X.

VI-A - 5.1 Un premier exemple : la multiplication de deux entiers


Supposons que nous manipulions des entiers de trs grande taille (plusieurs centaines d'octets) et que nous souhaitions les multiplier. Nous sommes confronts au problme suivant
Problme Produit Entre : a, b : entier Sortie : aob

Ici, nous considrons comme oprations lmentaires, les seules oprations de lecture d'un bit, de modification d'un bit, d'accs au bit suivant, de suppression du bit de poids faible (division par 2 not n"1) ou d'insertion d'un nouveau bit de poids faible (multiplication par 2 not n"1).

- 34 -

Initiation l'algorithmique par Denis Lapoire

VI-A-1 - 5.1.1 Un premier algorithme


Un premier algorithme est le suivant
fonction produit(a,b: entier): entier res +- O tantque b O faire si estPair(b) res +- addition(res,a) a +- a " 1. b - b " 1. retourner res

Cet algorithme utilisant la fonction addition de complexit linaire en la taille des entres a et b, la complexit de produit est quadratique car tant exactement gal e(taiiie(a) taiiie(b)) = e(n2) avec n taille(a) + taille(b) (on rappelle que la taille d'un entier a est le nombre de bits de se reprsentation binaire log (a)). Cstret algorithme est quadratique. Peut-on faire mieux? Clairement, pour multiplier deux entiers a et b, chaque bit compte la modification d'un seul bit modifie le rsultat. Aussi, doit-on lire chacun des bits de a et chacun des bits de b. En consquence de quoi, tout algorithme rsolvant Produit est de complexit en temps au moins linaire.

VI-A-2 - 5.1.2 Un second algorithme


Notons n la taille maximale de a et b. Quitte incrmenter n, nous pouvons supposer que n est un entier pair. Dcomposons a sous la forme a = 2 + a2 a2 est compos des bits de poids faibles de a; a1 est compos des bits de poids forts de a. Dcomposons b sous la forme b = b1 2 + b2. L'galit vidente a b = (a1 b1). 2 + (a1 b2 + a2 b1). 2 + a2 b2 entrane l'galit a b = (ai + a2)(bi + b2). 2 + a1 b1o (2 - 2) + a2 b2 (1- 2) Apparat dans cette dernire galit, un algorithme de multiplication d'entiers bine plus efficace que l'algorithme traditionnel. Que nous dit cette galit, pour multiplier a par b il faut en fait 1 2 3 dcomposer l'entre (a, b) en trois nouvelles entres: (ai+a2, b1+b2), (ai, b1) et (a2,b2). appliquer rcursivement le produit sur chacune de ces entre. Notons 51, S2 et s3 les produits associs. recomposer le rsultat final s l'aide de ces solutions partielles s1, 2 et s3 de la faon suivante

s s1o 2 + 2o - 2 2 + s3- 53o 2 L'algorithme peut s'crire


fonction produit2(a,b: entier) :entier n +- taille(a,b) si n= 1. si (a=1. ET b=1) retourner 1. sinon retourner O p +- n " 1. ; p= (a1,a2) +- dcomposition(a,n)

- 35 -

Initiation l'algorithmique par Denis Lapoire

(b1,b2) +- dcomposition(b,n) i +- produit(addition(a1,a2),addition(b1,b2)) s2 +- produit(a1,b1) s3 +- produit(a2,b2) res +- s"p ; signifie : res +- s2 res - addition(res, s2"n) res +- soustraction(res, s2"p) res +- addition(res, s3) res +- soustraction(res, s3"p) retourner res

VI-A-3 - 5.1.3 valuation de la complexit


Notons f N -* N* la fonction de complexit en temps. Pour simplifier l'expos, la taille d'un couple est considr le maximum des tailles des deux entiers. Observant que pour multiplier deux entiers a et b de taille chacun au max n, il est ncessaire de 1 2 3 de dcomposer ces entiers et produire les trois couples d'entiers. Chacune des oprations (dcomposition, taille, addition, dcalage, affectation) est de complexit 0(n). La complexit de la dcomposition est e(n). de raliser trois appels rcursifs sur ces trois couples de taille chacun . de recomposer la solution finale partir des trois solutions partielles. Cette recomposition ncessite 2 additions, 2 soustractions, 4 dcalages droits chacune de ces opration est de complexit en temps 0(n). La complexit de la recomposition est e(n).

En clair, la fonction complexit f(n) est dfini rcursivement par f(1) = 1 et f(n) =n+3f() Nous verrons comment rsoudre un tel systme d'quations. Nous pouvons ici le rsoudre la main. La solution est f(n) = n + 3( + 3( +...)) = n(() + (i)' + n.(2(n)) qui est gal no nmn()/mn(2). Observant que 1 + ln()/ ln(2) est gal ln(3)/ln(2) = 1n2(3), nous avons f (n) = nmn2(3) n"58 Cet algorithme est donc meilleur que le premier algorithme de complexit e(n2). De nouvelles amliorations "Divide and conquer" sont possibles qui permettent pour tout rel E > O de fournir un algorithme solution de Produit de complexit en temps e(n+c). D'autre part des techniques utilisant les transformes de Fourier permettent en temps linaire e(n) de rsoudre ce mme problme. Ainsi, le produit est de mme complexit qu'une addition ou qu'une comparaison.

VI-B - 5.2 valuation de la complexit


valuer la complexit d'un algorithme se fait en deux temps.

VI-B-1 - 5.2.1 Dfinition rcursive de la fonction


Cette premire peut tre immdiate. Il est ncessaire de projeter la dfinition rcursive de l'algorithme en une dfinition rcursive de la fonction complexit en temps. Nous pouvons alors obtenir par exemple l'quation f(n) = f(fl 3) + 6 f(2 1) + 3 n + + 879 Cette quation doit tre dbarasse des termes marginaux, des constantes multiplicatives n'apparaissant pas dans le terme rcursif. Nous obtenons alors pour quation g(n) = 7 g() + g

- 36 -

Initiation l'algorithmique par Denis Lapoire

Exercice 18 Dmontrer que les fonctions f et g vrifiant les deux systmes d'quation prcdent vrifient f = () et donc g = e(f).

VI-C - 5.3 Rsolution de certaines fonctions N - N dfinies rcursivement


Il n'existe pas de mthode gnrale pour rsoudre une quation. Les quations que nous proposons de rsoudre sont de la forme g(n) - a g() Si votre dfinition rcursive n'est pas de cette forme, il faut tenter de s'y ramener par tous les moyens. Souvent, les moyens prsents dans la section prcdente suffisent. Parfois, nous avons une inquation de la forme : f(n) < a f() + nk. Auquel cas, la conclusion que l'on peut en tirer est f(n) = O(g(n)) avec g solution de l'quation prcdente. La solution de l'quation est gale : 1 2 3 g(n) = O(nb(a) ln(n)) si a = b' c.a.d si k = lnb(a). g(n) = O(n(a)) si a > bk. g(n) = O(nk) si a < bk.

preuve Soit g la fonction dfinie par: g(n) = a g() + nk. Pour tout entier n on a: g(n) =nk+a.(g()). g(n) = nk + a ((n)k + a g(n) = nk(1 t ()2 . .. t ()1nb(n)).

L'observation que toute somme de la forme 1 + r + ... + r1 dfinie partir d'un terme r constant est gale l+l donce(l) sir=1. (r' - 1)/(r - 1) donc 0(r1) si r> 1. (r' - 1)/(r - 1) donc 0(1) si r < 1.

permet de conclure 1 2 3 si a = bk, g(n) = O(nl(a) ln(n)) puisque k = lnb(a) si a > b', g(n) = e(nk ()1nb(n)). Observant que ()mflb(fl) est gal lna(n) a/ (() b ) b ' c'est dire l(a), on obtient g(n) = O(nl(a)). si a < bk, g(n) = e(nk)

Exercice 19 Pour raliser le produit de deux entiers, une autre quation vrifie par a b est ab= (a1 .bi).2n +(ai.b2+a2.bi).2 +a2b2 Cette quation fournit un algorithme rcursif. 1 2 3 4 5 6 crire cet algorithme en utilisant les fonctions utilises dans produit2. crire la dfinition rcursive de la fonction complexit en temps Rsoudre cette quation et calculer de fait cette fonction complexit. Calculer la fonction complexit en espace. Comparer ces diffrentes complexits avec celles des algorithmes solution de Produit. Conclure en comparant cet algorithme aux autres solutions.

- 37 -

Initiation l'algorithmique par Denis Lapoire

VI-D - 5.4 Un deuxime exemple : la multiplication de deux matrices


Nous pouvons nous inspirer du produit de deux entiers, pour raliser le produit de deux matrices carres
problme ProduitMat Entre : deux matrices X Y carres de mme taille Sortie : le produit matriciel de X et Y

Notons Z la matrice produite. Dcomposant chacune des matrices carres X, Y et Z de mme taille suppose paire en des matrices A, A, B, C, D, E, F, G, H, I, J, K, L, de la faon suivante
ABI EF IJI X=CD Y=GH Z=KL

VI-D-1 - 5.4.1 Premire mthode


La premire mthode dcoule des quations videntes
I J K L = = = = AE AF CE CF + + + + BG BH DG DH

Exercice 20 En vous inspirant de la section traitant du produit de deux entiers: 1 2 3 4 5 crire un algorithme rsolvant ProduitMat utilisant la mthode dcrite plus haut. Vrifier que l'quation vrifie par la fonction complexit en temps est f(n) = 8f() + n o n est taille de la matrice (9 pour une matrice 3 3). Vrifier que la solution de cette quation est O(n). Calculer la complexit en espace. Conclure en comparant cet algorithme avec d'autres solutions a ce mme problme.

VI-D-2 - 5.4.2 Seconde mthode dite de Strassen


Reprenant les notations de la section prcdentes, la seconde mthode dcoule des galits suivantes Pi = A(G-H) P5 = (A+D)(E-H) P2 = (A+B)H P6 = (B-D) (F+H) P3 = (C+D)E P7 = (A-C) (E+G) P4 = D(F-E) I = P5 + P4 - P2 + P6 J = Pi + P2 K = P3 + p4 L = P5 + Pi - P3 - P7

Exercice 21 1. Vrifier la correction des quations proposes. 1 2 3 4 Vrifier la correction des quations proposes. En vous inspirant de la section traitant du produit de deux entiers, crire un algorithme rsolvant ProduitMat utilisant la mthode dcrite plus haut. Vrifier que l'quation vrifie par la fonction complexit en temps est f(n) = 7. f() + n o n est taille de la matrice (9 pour une matrice 3 3) que la solution de cette quation est 0(n" 7) 0(n'403).
- 38 -

Initiation l'algorithmique par Denis Lapoire

5 6

Calculer la complexit en espace. Conclure en comparant cet algorithme avec d'autres solutions a ce mme problme.

VI-D-3 - 5.4.3 Conclusion


Une solution algorithmique amliore l'algorithme de Strassen (O(n"403) et fournit un algorithme de complexit 0(n1138) (Coppersmith & Winogend). Pour des raisons videntes, le produit de deux matrices ncessite de lire chacun des lments de la matrice et ncessite au moins 0(n) oprations. Peut-on l'image du produit de deux entiers (ou de deux vecteurs) atteindre cette limite 0(n) ou sinon, s'en rapprocher davantage? La question est ouverte.

VII - Chapitre 6 Programmation Dynamique


Considrons l'algorithme suivant
fonction toto(s:squence d'entiers) :entier si longueuer(s) = 1 alors retourner s1 sinon retourner toto(extractl(s)) + toto(extract2(s)) o extractl et extract2 extraient deux sous-squences de s.

Notons n la longueur de la squence s. Supposons pour simplifier que la complexit de extractl et extract2 est 0(1). Dans le cas o extractl(s) et extract2(s) sont systmatiquement de longueur < avec b > 1, nous nous trouvons face un algorithme "Divide and Conquer" de complexit en temps polynomial car solution de g(n) = 1 + 2 contrario, Supposons par exemple que extractl (s) (resp. extract2 (s) retire un unique lment de s par exemple le premier (resp. le dernier). La fonction complexit en temps vrifie l'quation g(n) = 1 + 2 g(n - 1) et est gale 0(2") L'algorithme est exponentiel et est impraticable (le traitement d'une squence de 100 lments ncessite un sicle et ce mme si 1 milliard d'oprations lmentaires sont excutes par seconde). L'observation des calculs effectus par toto nous montre que l'appel sur la squence (1,2,3,4,5,6) entrainel'excution de toto sur les squences (1,2,3,4,5) et (2,3,4,5,6). Ce qui provoquera rcursivement 4 appels sur les squences (1,2,3,4), (2,3,4,5), (2,3,4,5) et (3,4,5,6). Nous voyons ici que par deux fois toto est excut sur la squence (2,3,4,5). Si on dtaille le nombre de fois o les appels sont excuts sur chacune des sous squences nous obtenons le dessin suivant
1,2,3,4,5,6) :1 (1,2,3,4,5):1 (2,3,4,5,6):1 (1,2,3,4): 1 (2,3,4,5):2 (3,4,5,6):1 (1,2,3):1 (2,3,4):3 (3,4,5):3 (4,5,6):1 (1,2):1 (2,3):4 (3,4):6 (4,5):4 (5,6):1 (1):1 (2):5 (3):1O (4):1O (5):5 (6):1

Il est facile d'observer que le nombre d'appels sur les squences de longueur 1 est exponentiellement proportionnel son oppos soit 26 : 2 appels sur les squences de longueurs 1 ont t excuts alors que 6 en tout auraient suffit. L'ide de la programmation dynamique repose sur l'ide de raliser un compromis espace-temps, c'est dire d'viter de rpter les mmes calculs quitte, pour viter ces rptitions, utiliser une mmoire auxiliaire pour se rappeler des calculs effectus.

VII-A - 6.1 Une solution de programmation dynamique


Pour mmoriser les calculs, nous avons besoin de deux informations:
- 39 -

Initiation l'algorithmique par Denis Lapoire

1 2

la premire djCalc indique pour toute squence si le calcul de toto a dj t effectu. la seconde valeurs indique pour toute squence pour laquelle le calcul de toto a t effectu, la valeur de ce calcul.

Supposons que extractl (s) supprime le premier lment de la squence s alors que extract2(s) supprime le dernier. Ici, toute sous-squence extraite t d'une squence initiale s peut tre reprsent par un couple d'entiers (i, i) form du rang du premier lment de t relativement s et du rang du dernier lment de t relativement s. L'algorithme devient alors
fonction totoDynamique(s:squence): entier n +- longueur(s) djCalc +- matriceCarre(n,fauxO) valeurs +- matriceCarre(n,O) (djCalc,valeurs) +- totoDynamRec(djCalc,valeurs,1,l) retourner valeurs[1][n] fonction totoDynamRec(djCalc,valeurs: matrice,i,j :entiers) matrice X matrice si djCalc[i] [j] retourner (dj Calc ,valeurs) sinon si i=j x +- imeElment(s,i) sinon (djCalc,valeurs) +- totoDynamRec(djCalc,valeurs,i,j-i) (djCalc,valeurs) +- totoDynamRec(djCalc,valeurs,i+i,j) x +- valeurs [i] [j-i] + valeurs [i+i] [j] djCalc[i] [j] + vraiO valeurs[i][j] +- x retourner (dj Calc ,valeurs)

valuation de la complexit de totoDynamique Notons n la longueur de la liste s. La complexit en espace est li la taille des deux matrices djCalc et valeurs soit 0(n2) et la taille maximal de la pile d'appel 0(n) soit un total de 0(n2). La complexit en temps est gal 0(n2). Cette complexit est de aux hypothse faites en introduction qui supposaient les complexits de extracti et extract2 constantes. la complexit de la construction des deux matrices djCalc et valeurs. au fait que l'instruction x<-valeurs [i] [j-i]+valeurs [i+i] [j] est excute une unique fois pour tout couple (i, i) avec j <j. Ainsi, le nombre de fois o la fonction totoDynamiqueaec est appel est exactement 1 plus deux fois le nombre de couples (i,j) avec 1 <j < <nc'est dire 1+(n-1)'n = 0(n2). En consquence, nous avons un algorithme quadratique 0(n2) alternative effective un algorithme toto impraticable car de complexit exponentielle 0(2j.

VII-A-1 - 6.1.1 Autre alternative


Dans l'exemple prcdent, nous pouvons abandonner l'criture rcursive et dynamique et obtenir un meilleur algorithme qui organise itrativement le remplissage de la matrice valeurs en prenant des couples (i, j) de faon faire crotre j - i. Cette connaissance nous permet ainsi de faire l'conomie et de la matrice dj Calc et de la pile d'appel induite par tout algorithme rcursif. L'algorithme est
fonction totoltratif (s : squence): entier 1 +- longueur(s) valeurs +- matriceCarre(l,O) pour i de 1 1 faire pour j de 1 1 faire si i=j alors valeurs[i] [i] = imeElment(s,i) sinon - 40 -

Initiation l'algorithmique par Denis Lapoire

valeurs [i] [j] + valeurs [i] [j-1] + valeurs [i+1] [j] retourner valeurs [1] [n]

VII-A-2 - 6.2 Bien fond de l'approche dynamique


L'existence d'un algorithme itratif aussi simple que totoltratif est lie notre capacit prdire quelles sont les sous-squences de s sur lesquelles le calcul doit tre effectu (ici toutes les sous-squences de la forme (si, . . . , s) avec s = (si,. . . , sa)) et dans quel ordre elles doivent tre values (ici selon j - i croissant). Le caractre polynomial de totoltratif tait possible car l'ensemble de ces sous-squences tait de cardinalit polynomiale ici e(n2). Parfois cette connaissance est absente et seule une approche dynamique illustre par totoDynamique est possible. Supposons que extractl et extract2 extraient de toute squence s des sous- squences selon des algorithmes complexes. Par exemple
fonction extractl(s:squence):squence Y notation s = (s1,.. .,s) si s1 + 2 < s3 + 3 alors retourner (s1,s3,. . . ,s) sinon si s2 s4 alors retourner (s2,s4,. . . ,s) sinon si etc

cause d'une telle complexit, il est possible priori que toute sous-squence de s ait une valuation ncessaire celle de s. Or le nombre de sous-squences de s est exponentiel e(2) : par exemple la squence (1, 2, 3) de longueur 3 admet exactement 7 = 2 - 1 sous-squences : Q, (1), (2), (3), (1, 2), (1, 3), (2, 3). Il n'est alors pas possible d'valuer toutes les sous squences de s comme l'a ralis totoltratif. Il nous faut valuer que les sous-squences rellement ncessaires, c'est dire celles rencontres lors du calcul rcursif. L'approche est celle utilise par totoDynamique la diffrence prs qu'il faut reconsidrer la dfinition de djCalc et de valeurs. Sans rentrer dans les dtails, nous pouvons supposer djCalc est un ensemble de squence dans lequel nous pouvons ajouter toute nouvelle squence (fonction ajouter) et dans lequel nous pouvons dcider de l'appartenance d'une squence cet ensemble (fonction appartient). valeurs est un ensemble de couples (t ,v) forms d'une squence t et d'un entier y dans lequel nous pouvons extraire pour une squence donn t la valeur entire associe y dans l'ensemble valeurs (fonction calcValeur). L'algorithme devient alors
fonction totoDynainique2(s:squence): entier (djCalc,valeurs) +- totoDynainaec2(ensVide() ,ensVide() ,s) retourner calcValeur(valeurs,s) fonction totoDynamRecG(djCalc,valeurs: ensemble,s : squence) ensemble X ensemble si appartient(s,djCalc) retourner calcValeur(valeurs,s) sinon si longueur(s)=i x - uniqueElment(s) sinon t +- extracti(s) u +- extract2(s) (djCalc,valeurs) +- totoDynamRec2(djCalc,valeurs,t) (djCalc,valeurs) +totoDynamRec2(djCalc,valeurs,u) x +- calcValeur(valeurs,t) + calcValeur(valeurs,u) djCalc +- ajouter(djCalc,s) valeurs +- ajouter(valeurs,(s,x)) retourner (dj Calc ,valeurs)

La complexit de cet algorithme dpendra naturellement de; de la longueur de la squence initiale s. la cardinalit N de l'ensemble des sous-squences dont l'valuation est ncessaire la squence initiale s.
- 41 -

Initiation l'algorithmique par Denis Lapoire

de la complexit des oprations calcValeur, appartient, ajouter. Une implmentation trs nave des ensembles djCalc et valeurs permet

une complexit des primitives en e (N n), qui offre une complexit gnrale pour totoDynamique2 gale C(n N2). Une meilleure implmentation (dans certains cas) offre des complexits pour les primitives gales C(n) et donc une complexit gnrale gale C(n N). La complexit est principalement li au nombre N de sous-squences ncessairement valuables pour valuer s. Si ce nombre est polynomial, la programmation dynamique offre un algorithme (de complexit en temps) polynomial. Si ce nombre N est exponentiel, il n'existe, sauf cas singulier, aucune solution algorithmique en temps polynomial qu'elle soit dynamique ou autre.

VIII - Chapitre 7 Algorithme Glouton


L'approche "Divide and Conquer" construit une solution aprs avoir dcouper l'entre initiale en plusieurs sousentres et aprs avoir calculer les solutions partielles chaque nouvelle sous-entre. La construction de la solution se fait en fait aprs avoir parcouru toute l'entre. L'approche gloutonne diffre de celle-ci en construisant une partie de la solution de faon dfinitive.

VIII-A - 7.1 Un premier exemple : le rendu de monnaie


Soit E l'ensemble des monnaies en euro. Le problme de la boulangre est de rendre une valeur S en euro en utilisant un nombre minimal de pices.
problme RenduDeMonnaie Entre : S : entier, E : ensemble d'entiers Sortie : une squence d'entiers de E de somme S et de longueur minimale L'algorithme s'crit de faon rcursive de la faon suivante fonction renduRec(S:entier ; E: ensemble d'entiers): squence d'entiers si S=O retourner O sinon calculer x la plus grande valeur de E infrieure ou gale S retourner ajouter (x , renduRec (S-x)) ou ainsi de faon itrative fonction rendulter(S:entier ; E: ensemble d'entiers): squence d'entiers solution +- squenceVide() tantque S O faire calculer x la plus grande valeur de E infrieure ou gale S solution +- ajouter(x,solution) S+-S-x retourner solution

Cet exemple illustre ce qu'est un algorithme glouton en bauchant la solution sans prendre connaissance de la totalit de l'entre : en effet, pour rendre la valeur de 17 centimes, seul le premier chiffre compte (le chiffre 1) et dtermine de rendre une pice de 10 centimes si S vaut {1, 2, 5, 10, 20, 50}.

VIII-A-1 - 7.1.1 Correction


La correction de cet algorithme est li au choix de l'ensemble E. Si l'ensemble des pices europennes avait t {1, 4, 6} l'algorithme aurait t incorrect : il associe la valeur 8 la squence (6, 1, 1) qui n'est pas optimale, la solution optimale tant (4, 4).

- 42 -

Initiation l'algorithmique par Denis Lapoire

VIII-A-2 - 7.1.2 Amlioration


Pour des raisons de complexits en temps et en espace, une autre reprsentation de la squence solution est prfrable. En effet si E est gal {1, 2, 5, 10}, la solution associe la valeur 1000000 (resp .10100) est la squence compose de 10000 (resp. i0) lments gaux 10. Cet algorithme est donc ncessairement exponentiel. Une autre reprsentation peut se faire dans l'exemple E = {1, 2, 4, 10} par un tableau indic de 1 4 et indiquant le nombre de pices correspondant. L'algorithme est
fonction rendu(S:entier ; E: tableau d'entiers): tableau d'entiers solution +- tableau(4)(O) pour i de 1 4 faire solution[i] +S+-S-x retourner solution

VIII-B - 7.2 Deuxime exemple : optimisation de la location d'une salle


Supposer que vous proposiez une salle la location et ne pouvant tre lou que pour un vnement la fois vous souhaitiez maximiser le nombre d'vnements; chaque vnement e ayant une date de dbut de et une date de fin df. Exemple 9 Dans le cas de trois vnements (1, 10), (8, 13), (12, 20), une solution optimale est de retenir les deux vnements (1, 10) et (12, 20).

VIII-B-1 - 7.2.1 Premire tentavive


Un premier algorithme consiste retenir en priorit les vnements compatibles avec les vnements dj retenus qui sont de dure minimale
fonction reservi(E:ensemble d'vnements) : ensemble d'vnements reste +- E solution +- ensembleVide() tantque vrai() faire tenter de choisir un vnement e de date de dure minimale compatible avec solution si choix impossible retourner solution enlever e reste ajouter e solution

Cet algorithme est incorrect car il associe l'ensemble des vnements {(1, 10), (8, 13), (12, 20)} le singleton {(8, 13)} qui n'est pas optimal.

VIII-B-2 - 7.2.2 Deuxime tentavive


Un second algorithme consiste retenir en priorit les vnements compatibles avec les vnements dj retenus qui ont une date de dbut minimale
fonction reserv2(E:ensemble d'vnements) : ensemble d'vnements reste +- E solution +- ensembleVide() tantque vrai() faire tenter de choisir un vnement e de date de dbut minimale compatible avec solution si choix impossible retourner solution enlever e reste ajouter e solution

- 43 -

Initiation l'algorithmique par Denis Lapoire

Cet algorithme est incorrect car il associe l'ensemble des vnements {(1, 100), (2, 2), (3, 3),. . ., (10, 10)} le singleton {(1, 100)} qui n'est pas optimal la solution optimale tant {(2, 2), (3, 3), . . . , (10, 1O)}.

VIII-B-3 - 7.2.3 Troisime tentavive concluante


Un troisime algorithme consiste retenir en priorit les vnements compatibles avec les vnements dj retenus qui ont une date de fin maximale
fonction reserv3(E:ensemble d'vnements) : ensemble d'vnements reste +- E solution +- ensembleVide() tantque vrai() faire tenter de choisir un vnement e de date de dbut maximale compatible avec reste si choix impossible retourner solution enlever e reste ajouter e solution

On observe que cet algorithme associe l'ensemble {(1, 10), (8, 13), (12, 20)} la solutionoptimale{(1, 10), (12,20)} et l'ensemble {(1, 100), (2,2), (3,3),..., (10, 10)} la solution optimale tant {(2, 2), (3, 3),. . ., (10, 10)}. Cet algorithme est correct, a une complexit en temps linaire. Ces assertions sont laisss en exercice Exercice 22 Considrons l'algorithme rserv3. Supposons que l'ensemble des n vnements soit reprsent par deux tableaux d'entiers indics de 1 n et indiquant l'un la date de dbut (tableau dateDeb) et l'autre la date de fin (tableau dateFin). 1 Rcrire l'algorithme reserv3 en utilisant et en observant la proprit suivante: un vnement e qui n'a pas t retenu dans le contexte d'une solution courante solution ne peut tre retenu aprs; il peut ainsi tre supprim de l'ensemble reste. Pour cela vous devrez Indiquer comment reprsenter l'ensemble reste. Indiquer comment reprsenter l'ensemble solution. valuer la complexit de cette implmentation. Prouver par rcurrence la correction de l'algorithme reserv3.

2 3

VIII-C - 7.3 Conclusion


Un grand nombre d'algorithmes optimaux du point de vue de la complexit en temps sont d'origine gloutonne, en particulier ceux fonctionnant en temps linaires. De nombreuses thorisations de cette approche gloutonne existent. La plus gnrale tant celle utilisant des matrodes.

IX - Chapitre 8 Quelques algorithmes de tri


Un problme classique en informatique est celui du tri
problme Tri Entre : un ensemble d'entiers E Sortie : une squence trie compose de chacun des lments de E

Notons que mous aurions pu supposer que l'ensemble en entre tait une partie d'un univers d'lments muni d'un ordre total. Ce cas particulier fait aux entiers n'altre pas le caractre gnral des algorithmes que nous allons considrer. Nous verrons comment partir des deux mthodes vues dans les chapitres prcdents rsoudre un tel problme.

- 44 -

Initiation l'algorithmique par Denis Lapoire

IX-A - 8.1 Approche gloutonne


Une approche gloutonne consiste construire la squence finale en en dfinissant un premier lment : clairement, il suffit d'extraire de l'ensemble E son plus petit lment x et de continuer. On dduit un premier algorithme rcursif
fonction triGloutonRecursif(E: ensemble) :squence si estVide(E) alors retourner sequenceVide O sinon (e,E) +- extraireMinimum(E) retourner ajouterEnDebut(e ,triGloutonRecursif(E))

Cet algorithme se traduit immdiatementen l'algorithme itratif suivant


fonction triGloutonltratif(E: ensemble) :squence Solution +- squenceVideO; tantque E n'est pas vide faire (e,E) +- extraireMaximum(E) Solution +- aj outerEnFin (e ,Solution) retourner Solution

Cet algorithme trs gnrique n'indique pas la faon dont sont reprsents les ensembles ou les squences.

IX-B - 8.2 Une premire implmentation


Une premire solution consiste supposer que l'ensemble E est reprsent l'aide d'un tableau indic de 1 un indice n. L'ensemble courant sera reprsent par ce mme tableau et l'indice indDeb indiquant l'indice du premier lment (l'ensemble E tant form des lments indics par les indices de indDeb n). Extraire l'lment minimum de E consistant parcourir l'intervalle [indDeb,nj, calculer l'indice indMin du plus petit lment, changer les lments aux indices indDeb et indMin puis incrmenter indDeb. L'algorithme est ainsi:
fonction triGloutoni(T:tableau) :tableau n - longueur(T) indDeb - 1 pour indDeb de 1 n-1 faire indMin - indDeb pour i de indDeb+1 n faire si T[i] < T[indMin] alors indMin - i T - changer(T,indDeb,indMin) retourner E

L'algorithme a pour complexit en espace (1) et pour complexit en temps e(n2).

IX-C - 8.3 Une deuxime implmentation l'aide d'un tas


Ici, nous implmenterons nons pas l'algorithme qui extrait le minimum des lments restants mais son algorithme dual qui considre les lments maximums
fonction triGloutonRecursif2(E: ensemble) :squence si estVide(E) alors retourner sequenceVide O sinon (e,E) +- extraireMaximum(E) retourner aj outerEnFin (e, triGloutonRecursif (E)) fonction triGloutonltratif2(E: ensemble) :squence Solution +- squenceVideO; tantque E n'est pas vide faire (e,E) +- extraireMaximum(E)

- 45 -

Initiation l'algorithmique par Denis Lapoire

Solution +- ajouterEnFin(e,Solution) retourner Solution

La complexit de l'algorithme est lie la complexit de l'extraction du minimum. Si nous choisissons de reprsenter l'ensemble E par une squence sous forme de tableau l'extraction est en e(n), la complexit globale est en e(n2). Une solution trs rapide existe qui utilise un tas.

IX-C-1 - 8.3.1 Dfinition de haut niveau d'un tas


Un tas peut tre dfini comme un ensemble dans lequel 1 2 on peut extraire le plus grand lment. on peut ajouter tout nouvel lment.

Ainsi, le tas est un ensemble dgrad dans lequel on ne peut extraire d'autre lment que le plus grand! Nous verrons que cette restriction permet d'obtenir pour chacune de ces oprations une complexit en espace constante et en temps gale e(log(n)) o n est la cardinalit de l'ensemble considr.

IX-C-2 - 8.3.2 Implmentation d'un tas


Pour implmenter un tas, on utilise un arbre binaire c'est dire un objet qui contrairement l'objet mathmatique unidimensionnelle qu'est la squence (dessine sur une ligne) est un objet bidimensionnel (dessine sur une page). Un arbre est un ensemble d'lments qui admettent certains un fils-gauche et/ou un fils-droit. L'lment qui n'a pas de pre est appel la racine. Un tas est un arbre dans lequel 1 2 l'lment fils-gauche (resp. fils-droit) y d'un lment x vrifie y x. tous les niveaux de l'arbre sont remplis except ventuellement le niveau le plus bas qui cependant ne doit pas laiss de "trou" dans sa partie gauche (voir exemple ci-dessous).

Exemple 10 Ainsi, l'ensemble {100, 40, 50, 20, 30, 1, 4, 3, 5, 2} peut tre reprsent par l'arbre suivant

100 / \ 50 40 / \ /\ 20 30 1 4 /\ / 35 2

Cet arbre a pour racine 100. Le fils gauche de 100 est 50, son fils droit est 40 qui a pour fisi gauche 1 et fils droit 4.

IX-C-3 - 8.3.3 Ajouter un lment dans un tas


Pour ajouter un nouvel lment y dans un tas reprsent par un arbre, il suffit de le placer au plus bas niveau et le "faire remonter" de faon respecter la hirarchie pre fils. Cet algorithme est illustr par l'example ci-dessous et sera formellement crit dans la section suivante. Exemple 11 Ajouter l'lment 66 dans le tas de l'exemple prcdent consiste le placer au niveau infrieur droite de l'lment le plus droite et le faire remonter itrativement si il suprieur son pre

- 46 -

Initiation l'algorithmique par Denis Lapoire

100 100 100 / \ / \ / \ 50 40 50 40 66 40 / \ / \ /\ / \ /\ /\ 20 30 1 4 20 66 1 4 20 50 1 4 /\ /\ /\ /\ /\ /\ 3 5 2 66 3 5 2 30 3 5 2 30

IX-C-4 - 8.3.4 Extraire le maximum dans un tas


Pour extraire le maximum d'un tas reprsent par un arbre, il suffit de dplacer la racine l'lment le plus droite sur le dernier niveau, puis de faire "descendre" cet lment dans l'arbre de faon respecter la hirarchie pre fils. Cet algorithme est illustr par l'exemple ci-dessous et sera formellement crit dans la section suivante. Exemple 12 Supprimer le maximum dans le tas de l'exemple prcdent consiste dplacer la racine 30 et le faire descendre dans l'arbre en changeant l'lment courant ventuellement avec le maximum de son fils gauche et de son fils droit.

30 66 66 / \ / \ / \ 66 40 30 40 50 40 / \ /\ / \ /\ / \ /\ 20 50 1 4 20 50 1 4 20 30 1 4 /\ / /\ / /\ / 35 2 35 2 35 2

IX-C-5 - 8.3.5 Implmentation d'un tas-arbre l'aide d'un tableau


Une reprsentation simple et optimale d'un tas est l'utilisation d'un tableau dans lequel 1 2 3 la racine est l'indice 1 le fils gauche d'un lment l'indice j a pour indice 2 i. le fils droit d'un lment l'indice j a pour indice 2 i + 1.

Exemple 13 Ainsi, le tableau suivant


1 2 3 4 5 6 7 8 9 10 100 50 40 20 30 1 4 3 5 2

fournit une reprsentation du tas

100 / \ 50 40 / \ /\ 20 30 1 4 /\ / 35 2

On observe que le fils-gauche de l'lment 50 (indice 2) est l'lment 20 (indice 4). On observe que le fils-droit de l'lment 50 (indice 2) est l'lment 30 (indice s).

- 47 -

Initiation l'algorithmique par Denis Lapoire

IX-C-6 - 8.3.6 criture de l'algorithme


L'ensemble E sur lequel le tri est effectu est reprsent l'aide d'un tableau. Le tas utilis dont la cardinalit varie au cours de l'algorithme est en fait constitu par la partie gauche du tableau born par un indice cardTas. L'algorithme est
fonction triParTas(t:tableau) :tableau n +- longueur(t) pour i- 2 n t - ajouterTas(t,i) pour i- n 2 t +- changer(t,i,i) t +- descenteTas(t,i-i) retourner t

o les deux fonctions auxiliaires rsolvent les deux problmes dfinis par les Figures 8.1 et 8.2.

IX-C-7 - 8.3.7 valuation de la complexit


Comme cela sera tabli dans les deux sections suivantes, les deux fonctions auxiliaires ajouterTas et descenteTas ont une complexit en espace en (1) et une complexit en temps dans le pire des cas en e(log(i)). On en dduit que triParTas a une: 1 2 complexit en espace de e(1). L'espace mmoire utilis est, except quelques variables pour grer des indices, celui du tableau fourni en entre. Il s'agit donc tri "sur place". complexit en temps dans le pire des cas gale e(nlog(n)). Du fait de l'galit e(nlog(n)) = ZiE[lfl] ilog(i).

Pour ces deux raisons, cet algorithme de tri est optimal.

- 48 -

Initiation l'algorithmique par Denis Lapoire

criture de ajouterTas Une solution Aj outerTas est l'algorithme suivant illustr par l'exemple 11:
fonction ajouterTas(t :tableau,cardTas : indice) :tableau i - cardTas tantque i>i ET t[i]>t[i/2] faire t +- changer(t,i,[i/2]) i +- [i/2] retourner t

La complexit en espace de cet algorithme est (1) et en temps (dans le pire des cas) en e(log(n)) avec n := cardTas : en effet chaque passage de boucle j est au moins divis par deux. Il faut donc au plus log(n) passages de boucles pour que i > 1 soit valu faux. Exercice 23 En reprenant l'exemple du tas de l'Exemple 11, fournir les tats diffrents du tableau reprsentant ce tas au cours de l'algorithme ajouterTas. criture de descenteTas Une solution DescenteTas est l'algorithme dfini par la Figure 8.3 et illustr par l'Exemple 12 La complexit en espace de cet algorithme est e(1) et en temps (dans le pire des cas) en e(log(n)) avec n := cardTas : en effet chaque passage de boucle j est au moins multipli par deux. Il faut donc au plus log(n) passages de boucles pour que 2 i > cardTas soit vrifi. Exercice 24 En reprenant l'exemple du tas de l'Exemple 12, fournir les tats diffrents du tableau reprsentant ce tas au cours de l'algorithme descenteTas.

- 49 -

Initiation l'algorithmique par Denis Lapoire

IX-D - 8.4 Approche "Diviser pour rgner"


La mthode "Diviser pour rgner" consiste "dcomposer" l'instance en deux (ou plusieurs) nouvelles instances, appliquer rcursivement l'algorithme de tri sur ces deux nouvelles sous-instances et recomposer partir des deux rsultats partiels le rsultat gnral. L'algorithme de dcoupe vient trs naturellement : il s'agit de partitionner un ensemble en deux parties. Un algorithme assez gnrique est alors
fonction tri(E:ensemble) :squence (F,G) +- partition(E) retourner fusionner(tri(F) ,tri(G))

Notons ds prsent les proprits souhaites des algorithmes de partition et de fusion. Notons n la cardinalit de l'ensemble E. En supposant que l'on arrive raliser les calculs de partition et de fusion en au plus n oprations lmentaires et partitionner E en deux parties de cardinalit gales, la fonction complexit en temps (dans le pire des cas) f de tri vrifie
- 50 -

Initiation l'algorithmique par Denis Lapoire

f(n) =n+2.f() La fonction f est donc gale e(nln(n)). Le rsultat est alors optimal: nous ne connaissons pas d'algorithme de tri de complexit en temps infrieur O(nln(n)). Observons ds prsent, l'enjeu de dcomposer E en deux parties de cardinalit proche. Si cette contrainte n'est pas respecte, et si l'on autorise de partitionner E en deux parties une ayant 1 lment et l'autre n - 1 lments. L'quation devient f(n) <n+f(n-1) La fonction f est donc gale 0(n2). Lors des diffrents algorithmes tudis, nous reprsenterons les ensembles ainsi que les listes l'aide de tableaux. D'autres algorithmes existent qui utilisent d'autres faons de reprsenter les ensembles partir de listes, files ou arbres. L'algorithme gnral de tri a pour dfinition
fonction tri(T:tableau) :tableau retourner triRec(T, 1, longueur (T)) et utilise une fonction auxiliaire triRec qui rsout rcursivement le problme suivant problme TriRec Entre : un tableau T, deux indices i i j longueur(T) Sortie : un tableau U contenant les mmes lments que T tel que U[i. .j] est tri U[i. .j] contient les mmes lments que T[i. .j]

IX-D-1 - 8.4.1 Premire solution algorithmique de TriRec


Le premier algorithme est bas sur une faon naturelle de dcoomposer un tableau : il suffit de calculer l'indice du milieu (-t) sans dplacer les lments.
fonction triReci(T : tableau ; i,k : indices) : tableau si i = k retourner T j T +- triReci(T,i,j-i) T +- triReci(T,j,k) T +- fusion(T,i,j,k) retourner T

La difficult principale est ici de rsoudre le problme


problme Fusion Entre : un tableau T, trois indices i < j < k tels que les sous-tableaux T[i. .j-i] et T[j. .k] sont tris. Sortie : un tableau U contenant les mmes lments que T tel que U[i. .i-i] = T[i. .i-i] U[i. .k] est tri U[k+i. .n] = T[k+i. .n]

L'algorithme fusion (Figure 8.4) utilise deux tableaux auxiliaires gauche et droit dans lesquels nous ralisons une copie des sous-tableaux T[i. .j-i] et T [j k]. Ces copies sont ralises par la fonction copie. Exercice 25 crire un algorithme itratif inspir de triReci. L'ide tant de fusionner les sous-tableaux de longueur 2, puis ceux de longueur 4, puis ceux de longueur 8. Evaluer la complexit en temps et en espace de celui-ci. Comparer ces complexits celles de triReci. Conclure.

- 51 -

Initiation l'algorithmique par Denis Lapoire

valuation de la complexit La complexit en temps de fusion est gal k-i-l-i la longueur du tableau symboliquement pass en argument. Ainsi, l'quation fournissant la complexit en temps de triReci est g(n) = 2 g() n La complexit en temps de triReci est ainsi e(n log(n)). La faiblesse de cet algorithme est l'opration copie qui utilise une mmoire auxiliaire de taille e(n).

- 52 -

Initiation l'algorithmique par Denis Lapoire

IX-D-2 - 8.4.2 Seconde solution algorithmique de TriRec


Le prcdent algorithme consistait 1 2 en temps constant, dcomposer un tableau, par simple calcul d'un indice. en temps linaire recomposer un tableau tri partir des sous-tableaux tries.

Le second algorithme prsent ici consiste 1 2 en temps linaire, dcomposer le tableau. en temps constant recomposer un tableau tri partir des sous-tableaux tris.

Pour recomposer en temps constant un tableau tri l'aide de deux sous-tableaux tris, une seule solution est possible : faire en sorte que les lments du sous- tableau de gauche soient infrieurs ou gaux aux lments du sous-tableau de droite. Pour raliser cela, on choisit dans le tableau initial un lment appel pivot autour duquel cette dcomposition se fera. Ces deux tches sont dvolues deux fonctions rsolvant les deux problmes suivants
problme ChoixPivot Entre : un tableau T, deux indices 1 i j longueur(T) Sortie : un indice indPivot appartenant [i,j] problme Distribuer Entre : un tableau T, trois indices i,j,indPivot tels que 1 < < indPivot < j longueur(T) Sortie : un tableau u et un indice k tels que: u contient les mmes lments que t u[1. .i-1] = t[1. .i-1] u[j-l-1. .n] = t[j+1. .n] u[k] = t[indPivot] VaE[i,k-1] u[a]<u[k] VaE[k-l-1,j] u[k] u[a]

La Figure 8.5 fournit la dfinition de l'algorithme rcursif.

- 53 -

Initiation l'algorithmique par Denis Lapoire

Une solution algorithmique pour Distribuer Une solution algorithmique au problme Distribuer est fourni par la Figure 8.6.

Il est facile d'observer que la complexit en temps de distribuer est linaire en la longueur du tableau T considr (c'est dire p := jo - io + 1) soit e(j0 - i0).

IX-D-3 - 8.4.3 Diffrentes variantes lies au choix du pivot


L'algorithme gnral triRec2 admet plusieurs variantes qui dpendent de la faon de choisir le pivot. Rappelons que si la complexit en temps du choix du pivot (c'est le cas) n'excde pas celle de distribuer (en e(n) o n est la longueur du tableau symboliquement fourni en entre) l'inquation fournissant la complexit en temps dans le pire des cas est f(n) <n+f(n-1) Auquel cas, la complexit est majore par n2. Si l'on souhaite obtenir une complexit faible, il nous faut partitionner l'ensemble en deux parties gales ce qui nous permet d'obtenir pour quation f(n)=n+2.f() et d'obtenir ainsi pour complexit n ln(n).

- 54 -

Initiation l'algorithmique par Denis Lapoire

IX-D-4 - 8.4.4 Le choix du premier pivot venu: le tri rapide


Le problme ChoixPivot admet pour premire solution
fonction choixPivoti(T:tableau ; i,j : indices) : indice retourner j

Point faible Cette solution de complexit en temps e(1) a le dsavantage d'offrir une complexit en temps dans le pire des cas pour triRec2 gale e(n2). Exercice 26 Pour tout entier n, notons T le tableau tri (1,2,. . . , n). 1 2 3 Dmontrer que pour tout n et tous indices j et j, distribuer(Tn,i,j ,i) retourne le couple (Tn, i). En dduire que l'quation dfinissant le nombre d'instructions lmentaires excutes sur de tels tableaux est g(n) = 1 + g(n - 1) + n En dduire que la complexit (dans le pire des cas) de triRec2 est e(n2).

Exercice 27 Quel est le nombre d'instructions lmentaires excutes sur un tableau lments tous gaux? Point fort Le premier point fort est la simplicit de l'algorithme! Le second est que la complexit en temps en moyenne, note f(n), est e(nlog(n)). Pour calculer cette moyenne, on restreint l'tude des tableaux dont les lments dfinissent un intervalle de la forme [1, n]. La preuve est l'objet de l'exercice suivant Exercice 28 1. Dmontrer que le nombre de tels tableaux de longueur n est exactement n!. 2. Dmontrer que l'intgrale de x ln(x) est gale x2 ln(x) - x2. En dduire que ZiE[ln] pln(p) = e(n2 ln(n)). 3. Dmontrer que f(n) vrifie l'quation (f(p)+f(n-p-1)) pE[1,n 1] Pour cela, utiliser le fait que l'ensemble des tableaux de longueur n se partitionne en n ensembles de mmes cardinalits, ceux dont le premier lment est 1, deux dont le premier lment est 2 etc. 4. Rsoudre cette quation et conclure. Algorithme dit "tri rapide" : mfiez-vous de son nom! Cet algorithme a pour nom, l'algorithme de tri rapide. Ce nom est un faux ami : en effet cet algorithme est de complexit en temps dans le pire des cas e(n2), il est donc de ce point de vue bien moins rapide que le tri par tas ou le tri mdian. Cependant, il offre du point de vue de la complexit en moyenne un rsultat optimal en e(n log(n)) quivalent celui du tri par tas ou du tri mdian (voir plus loin). Mieux une valuation fine du nombre d'instructions lmentaires montre qu'il est plus rapide que le tri par tas : sa complexit de la forme n log(n) prsente une constante multiplicative bien infrieure celle du tri mdian ou du tri par tas. Pour cette raison bien concrte, il est prfr aux deux autres tris. Il est en fait possible de fournir une variante amliore du tri rapide. C'est l'objet du point suivant.

- 55 -

Initiation l'algorithmique par Denis Lapoire

IX-D-5 - 8.4.5 Le choix d'un pivot alatoire


Nous pouvons amliorer l'algorithme suivant en choisissant pour indice un indice pris alatoirement dans l'intervalle [i,j]
fonction choixPivot2(T:tableau ; i,j : indices) : indice retourner alatoire(i,j)

La complexit en temps dans le pire des cas est conserve : il s'agit de e(n2). La complexit en moyenne est conserve : il s'agit de e(nln(n)). L'avantage est qu'ici pour tout tableau fourni en entre ( valeurs deux deux distinctes) l'esprance du nombre d'instructions est e(nln(n)). Ainsi, pour tout tableau, la malchance d'avoir un traitement en e(n2) instructions est faible. Ce algorithmes alatoires n'tant pas tudis dans ce cours, nous ne ne retiendrons que cette ide : quand nous avons choisir entre plusieurs options quivalentes, une bonne stratgie algorithmique est le choix alatoire.

IX-D-6 - 8.4.6 Le choix d'un pivot mdian


Soit E un ensemble n lments, nous appelons mdian le ime plus petit lment avec j := [j. Nous avons vu prcdemment, que l'on obtient une complexit en temps dans le pire des cas en n log(n) en partitionnant l'ensemble E initial en deux parties de cardinalit proche (cette condition est en fait non seulement suffisante mais aussi ncessaire voir Exercice 30). En d'autres termes il faut choisir pour pivot le mdian de l'ensemble E. Le calcul du mdian est ralis en rsolvant le problme plus gnral suivant
problme Slection Entre : un ensemble E, un entier iE [1,card(E)] Sortie : le ime plus petit lment de E

En supposant que E reprsent l'aide d'un tableau T de longueur n, le calcul du i-ime plus petit lment de T se fait de la faon suivante 1 2 3 en considrant comme bloc chacun des sous-tableaux de longueur 5 associs aux intervalles d'indice [1, 5], [6, 10], [11, 16] etc, on trie chacun des blocs. en considrant chacun des mdians des sous blocs (aux indices 3, 8, 13 etc), on calcule le mdian x (et son indice mdx) de ces mdians en utilisant de faon rcursive slection. on excute distribuer en prenant pour pivot ce mdian. On obtient ainsi un tableau T partitionn autour du mdian des mdians x l'indice not k, avec aux indices de 1 k - 1 des valeurs < x et aux indices de k + 1 n des valeurs x. si j = k on retourne x, sinon si j < k on calcule rcursivement slection sur l'entre (T[i ,k-i] , i) sinon on calcule rcursivement slection sur l'entre (T[ki-i,n] ,i-k).

Exercice 29 1 2 3 4 Dmontrer que k appartient l'intervalle [, ]. Dmontrer que la fonction complexit en temps f de slection vrifie l'inquation f(n) <n + f() + f() Rsoudre cette inquation en dmontrant que e(nln(n)) en est solution. Quelle serait la complexit de l'algorithme, si au lieu de considrer des blocs de 5, nous avions considrer des blocs de longueur 3. 7.

a b

- 56 -

Initiation l'algorithmique par Denis Lapoire

5. crire l'algorithme. Exercice 30 Dans l'algorithme triRec2, supposons qu'il existe un rel fix O < a <=1/2 tel que l'entier [k-i]/j-i+1 appartienne l'intervalle [a, 1 - a] 1 2 3 4 Que vaut a quand le pivot choisi est le mdian? crire l'quation vrifie par la fonction complexit en fonction de a? Rsoudre cette quation. Que pensez-vous de l'intrt d'un tel algorithme lorsque a=1/10, a=1/10^10 , a=1/10^10^10

- 57 Copyright 2008 - Denis Lapoire. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://alp.developpez.com/private/lapoire/

Vous aimerez peut-être aussi