Exercices sur les algorithmes et les structures de données - 1° partie, Exercices de Algorithmique et programmation des applications
Christophe
Christophe28 février 2014

Exercices sur les algorithmes et les structures de données - 1° partie, Exercices de Algorithmique et programmation des applications

PDF (154 KB)
32 pages
367Numéro de visites
Description
Exercices de mathématique - examen sur les algorithmes et les structures de données - 1° partie. Les principaux thèmes abordés sont les suivants: Introduction, Problemes, Algorithmes, Analyse des algorithmes.
20points
Points de téléchargement necessaire pour télécharger
ce document
Télécharger le document
Aperçu3 pages / 32
Ceci c'est un aperçu avant impression
3 shown on 32 pages
Télécharger le document
Ceci c'est un aperçu avant impression
3 shown on 32 pages
Télécharger le document
Ceci c'est un aperçu avant impression
3 shown on 32 pages
Télécharger le document
Ceci c'est un aperçu avant impression
3 shown on 32 pages
Télécharger le document
cours.dvi

Chapitre 1

Introduction

– Étude des problèmes calculatoires

– Algorithme = outil de résolution d’un problème.

– Algorithme de mise en oeuvre : introduction d’une notation, langage de

description algorithmique et de description des données.

– Un problème a généralement plusieurs solutions algorithmiques.

– Analyse d’algorithmes (complexité) : temps de calcul, taille des données,

croissance en fonction de la taille des données.

Des problèmes, des solutions algorithmiques, comparaisons selon temps

calcul, espace mémoire, facilité écriture, ...

6

1.1 Problèmes

1.1.1 Châıne de résolution de problèmes

Du problème à sa solution, il y a une châıne de traitements dans laquelle

l’algorithmique prend place.

Un problème admet des entrées et des sorties.

Problème réel

Expression du problème

Programme

Résultats

Algorithme

Analyse

Conception d’algorithme

Traduction

Exécution

ASD : La phase d’analyse correspond à la recherche d’une expression mathématique

d’un problème réel. Cette expression se présente généralement sous la

7

forme de relations entre les entrées et les sorties. (Elle présuppose

une connaissance parfaite du problème réel).

La phase de conception d’algorithme consiste à construire une procédure

de calcul permettant d’établir les relations désirées entre les données

d’entrée et les données de sorties. Cette procédure s’exprime généralement

au moyen d’un ensemble d’instructions à exécuter dans un ordre

précis. En effet, il s’agit de décrire un calcul s’effectuant possible-

ment en plusieurs étapes. L’algorithme apparâıt comme un outil de

résolution d’un problème.

Programmation : La traduction de l’algorithme présuppose le choix d’un

langage de programmation. L’exéxution du programme nécessite la

donnée des entrées.

L’ASD fournit des concepts généraux sur les algorithmes et les structures

de données qui sont utiles pour tous les langages de programmation.

La programmation consiste à prendre en considération la modularisa-

tion des programmes selon les structures syntaxiques disponibles. Elle gère

aussi des situations plus concrètes comme la gestion de la mémoire, les entrées

sorties, la gestion des erreurs. Les langages de programmation : machine

et évolués. Classes ou paradigmes de langages de programmation impliquant

différentes méthodologies de programmation.

Le génie logiciel consiste à prendre en compte la totalité de la châıne

qui est en fait un cycle, compte tenu des erreurs possibles à chaque étape et

de la maintenance du logiciel résultant.

8

1.1.2 Exemples de problèmes

Expressions plus ou moins immédiates selon les problèmes. L’expres-

sion des relations définissant le problème nécessite l’expression des données

d’entrée et de sortie. Pour l’expression du problème, on utilise des définitions

mathématiques. Mais pour concevoir un algorithme, on utilisera des Struc-

tures de contrôle permettant d’enchâıner les étapes du calcul, des Struc-

tures de données, qui sont une description de données implémentées dans

la mémoire d’un ordinateur, et de Types abstraits, qui sont des construc-

tions abstraites permettant d’associer des données et des opérations utiles

pour l’expression de l’algorithme.

1. RÉSOLUTION D’UNE ÉQUATION DU PREMIER DEGRÉ :

Entrée : a et b réels

Sortie : x réel tel que ax + b = 0

Solution calculable si a 6= 0. Méthode de calcul connue x = −b a

.

Structure de données : variable et constante.

Structure de contrôle : test

2. TRI

Entrée : Une séquence de n nombres < a1, a2, . . . , an >.

Sortie : Une permutation < a′1, a ′

2, . . . , a ′

n > de la séquence telle que

a′1 ≤ a′2 . . . ≤ a′n.

Solutions algorithmiques diverses à comparer selon temps de calcul,

taille données, cas de configurations des données (séquence presque

triée, ...).

Structure de données : notion de séquence de données −→ tableaux

9

Structure de contrôle : boucle Exemple. Donner une séquence d’entrée

et de sortie.

3. CARTE À COLORIER : il s’agit de colorier une carte avec un certain

nombre de couleurs. De façon à ce qu’elle soit lisible, deux régions

voisines ne doivent pas admettre la même couleur.

1 2 3

4 5

Soit la carte c représentée sur la figure. Elle admet l’ensemble de régions

R = {1, 2, 3, 4, 5}. La relation de voisinage entre deux régions est donnée par l’ensemble des couples : V = {(1, 2), (1, 4), (2, 3), (2, 4), (2, 5), (3, 5), (4, 5)}. Considérons l’ensemble de trois couleurs C = {c1, c2, c3}. Le résultat recherché est une fonction de R dans C satisfai- sant les critères souhaités. Le problème général peut s’exprimer comme

suit :

Entrée : c = (R, V ), C

Sortie : i : R −→ C, telle que ∀v = (r1, r2) ∈ V, i(r1) 6= i(r2).

Type abstrait graphe pour représenter une relation. Implémentation au

moyen de structure de données telles que tableaux à 2 dimensions, ou

de structures châınées.

10

1.1.3 Remarques

Parfois, un problème admet plusieurs solutions. Un problème est dit

déterministe si il admet une seule solution. Sinon, il est dit indéterministe.

Dans le cadre de ce cours, nous considèrerons surtout des problèmes déterministes.

Dans les cas indéterministes, il est possible de concevoir des solutions algo-

rithmiques énumérant toutes les solutions, ou bien produisant la solution la

meilleure selon un critère. (Voir programmation logique).

On appelle Instance d’un problème un problème muni de toutes ses

entrées nécessaires pour calculer la solution.

Il est malheureusement possible d’écrire des algorithmes incorrects (pro-

duisant des résultats ne vérifiant pas les relations requises) ou ne se terminant

pas. Un algorithme est correct si pour chaque séquence d’entrée il se termine

et fournit la sortie correcte.

1.2 Algorithmes

Les algorithmes seront décrits au moyen d’un pseudo-code proche des

langages C, Pascal ou Algol. Parfois le langage naturel pourra être utilisé.

Pour l’introduire, nous présentons d’abord l’exemple du tri par insertion.

1.2.1 Tri par insertion

– Main droite : cartes non triées,

– Main gauche : cartes triées.

– Initialisation : main gauche vide.

11

– Insertion de la première carte de la main droite dans la main gauche à

sa place.

TRI-INSERTION(tableau A) −→ tableau pour j ←− 2 à A.taille

faire cle ←− A[j] i←− j − 1 tant que i > 0 et A[i] > cle

faire A[i + 1]←− A[i] i←− i− 1

A[i + 1]←− cle retourner A

Il s’agit d’une fonction qui s’appelle TRI-INSERTION, prenant comme

entrée ou paramètre le tableau A et ayant en sortie ou en résultat un

tableau. On accède au i-ème élément du tableau A par la notation A[i]. Le

nombre d’éléments du tableau A est obtenu par A.taille.

– Deux boucles imbriquées. La première est la plus externe, la seconde,

la plus interne.

– Main droite : A de j + 1 à longueur de A

– Main gauche : A de 1 à j

– La première carte à transférer est la jième. La première valeur de j est

donc deux. (Le transfert de la première carte est réalisé en affectant j

à 2).

12

1.2.2 Éléments de base du langage de description al-

gorithmique

La présentation des algorithmes est donnée par une indentation s’appli-

quant aux instructions d’un même bloc séquenciel. Le découpage en lignes

est tel qu’une instruction simple apparâıt seule sur sa ligne.

Dans cette présentation, nous notons en minuscules et en gras les mots

clef du langage, et en majuscules, les autres formes.

1.2.3 Variables

Une variable possède

– un nom (identificateur) mnémonique fixé par l’utilisateur et permet-

tant de manipuler l’objet,

– une valeur courante (compatible avec le type) qui peut varier au cours

du déroulement de l’algorithme.

– un type, associé à la valeur de la variable.

Les variables de l’exemple sont : j, cle, A, i.

1.2.4 Constantes

Une constante est un objet similaire à une variable, mais ayant une

valeur fixe. Une constante a un type. Les constantes de l’exemple sont 2, 1,

0.

13

1.2.5 Types

Le type d’une variable (ou d’une constante) peut être simple (scalaire

entier, réel, . . . ) ou structuré (tableau à une ou plusieurs dimensions, struc-

tures, . . . ). Les types de l’exemple sont : entier (j, i, cle, 1, 2, 0), tableau

d’entiers à une dimension (A).

Remarque. Pas de déclarations de variables. Seules, les fonctions sont

signées. (cf types abstraits).

1.2.6 Instructions simples

– L’affectation : l’instruction d’affectation modifie la valeur d’une va-

riable. Elle est notée ←−. Les affectations de l’exemples permettent de modifier les indices pour parcourir et décaler le tableau, et modifier la

valeur de cle. Affectation multiple : x,y ←f(z).

– lire, écrire, ...

1.2.7 Structures de contrôle

Une structure de contrôle est un ensemble d’instructions qui s’exécutent

séquentiellement. Ces instructions sont soit des instructions simples, soit

des structures de contrôle.

14

Donner la syntaxe en langage C des structures de contrôle.

– Structure séquentielle :

s1

s2

...

sn

Exemple : lignes 2 et 3, 5 et 6.

– Structures conditionnelles ou sélectives (ou tests):

si P

alors S1

sinon S2

si P

alors S1

Décrire le fonctionnement.

– Structures itératives ou répétitives (ou boucles):

tant que P

faire S

répéter S

jusqu’à ce que 6 P pour I à P

faire S

Dans chaque cas, la structure de contrôle S est appelée le corps de la

boucle.

15

Exemple : lignes 1 et 4.

Décrire le fonctionnement.

– Procédures et Fonctions:

NOM(LISTE DE PARAMETRES TYPES) −→ type resultats S

Une fonction comporte pour tous ces chemins d’exécution une occur-

rence de l’instruction retourner .

Les paramètres sont passés par valeur, c’est-à-dire que la procédure

reçoit la valeur de ses paramètres. Nous préciserons plus loin, lors de

la présentation des structures de données, les valeurs associés à chaque

type.

1.2.8 Instructions d’échappement

Les instructions d’échappements permettent la sortie anticipée de struc-

tures de boucles.

– retourner : cette instruction s’utilise à l’intérieur d’une fonction pour

renvoyer un résultat. Elle est donc suivie de l’expression du résultat.

Dans l’exemple, le tri se fait sur place dans le tableau reçu en paramètre,

par des affectation à ses éléments. Il n’y a pas de résultat à retourner.

– continuer : cette instruction s’utilise à l’intérieur d’une structure répétitive

(ou boucle) pour se brancher sur le test de continuation.

– sortir: cette instruction s’utilise à l’intérieur d’une structure de contrôle

pour en sortir. (Branchement sur l’instruction suivant la structure de

contrôle).

Durée : 1H30

16

EXEMPLE. A = [5, 2, 4, 6, 1, 3] à faire tourner.

1.3 Récursivité

1.3.1 Conception récursive

Il existe diverses façons de concevoir des algorithmes. L’exemple du tri

par insertion procède de façon incrémentale : la taille de la partie du tableau

triée augmente effectivement à chaque itération. Une autre approche très

utile est la récursivité. Il s’agit de résoudre un problème de taille n en le divi-

sant en plusieurs problèmes similaires mais de tailles inférieures. Dans cette

approche, la fonction résolvant le problème s’appelle elle-même pour résoudre

les problèmes de tailles inférieures. La procédure de conception générale est

la suivante.

– Diviser le problème en plusieurs sous-problèmes similaires.

– Résoudre les sous-problèmes.

– Combiner les solutions des sous-problèmes pour obtenir la solution du

problème initial.

Quand on parvient à un sous-problème ne pouvant pas être divisé, il faut

alors le résoudre directement sans appel récursif. On parle du plancher de

la récursivité.

DÉFINITION. Une procédure (ou une fonction) est dite récursive si elle

fait appel à elle-même.

17

1.3.2 Exemples

n! = 1× 2× 3× . . .× n

1. Version itérative

FACTORIELLE-ITERATIVE(n)

r ←1 pour i ←n à 1 par pas de -1

r ←r * i retourner r

2. Version récursive

FACTORIELLE-RECURSIVE(n)

si n = 0

alors

% Plancher de la récursivité

retourner 1

sinon

% Combinaison du résultat du sous-problème

% pour obtenir le résultat du problème initial

retourner n * factorielle-récursive(n-1)

1.3.3 Fonctionnement

Prenons par exemple n=3 et regardons quelle est la suite d’appels obte-

nue.

18

Appels Résultat Environnement

factorielle-récursive(3) n * factorielle-récursive(n-1) n = 3

factorielle-récursive(2) n * factorielle-récursive(n-1) n = 2

factorielle-récursive(1) n * factorielle-récursive(n-1) n = 1

factorielle-récursive(0) 1

Observons l’expression obtenue et l’ordre dans lequel elle est calculée.

– 3 * factorielle-récursive(2)

– 3 * (2 * factorielle-récursive(1))

– 3 * (2 * (1 * factorielle-récursive(0)))

– 3 * (2 * (1 * 1))

– 3 * (2 * 1)

– 3 * 2

– 6

Le calcul nécessite 4 appels récursifs à la fonction. On constate que lors des

trois premiers appels, l’expression calculant le résultat ne peut être évaluée

qu’au retour de l’appel récursif. D’où la nécessité de conserver toutes les

valeurs prises par n au sein des différents appels afin d’étre en mesure de

calculer les multiplications au retour des appels récursifs. La struture de

donnée utilisée pour conserver ces valeurs est une pile (qui sera étudiée plus

loin dans ce cours). Ceci est un phénomène général de la récursivité : l’espace

mémoire crôıt avec le nombre d’appels imbriqués.

Comparons ce mécanisme avec celui mis en oeuvre pour exécuter la fonc-

tion itérative FACTORIELLE-ITERATIVE(n).

– r = 1, i = 3, n=3

19

– r = 3, i = 2, n=3

– r = 6, i = 1, n=3

– r = 6, i = 0, n=3

Dans cet algorithme, le calcul du résultat s’effectue progressivement à

chaque tour de boucle. Il est inutile de conserver les valeurs précédentes.

Seules les variables r et i sont donc nécessaires pour effectuer le calcul du

résultat.

20

Chapitre 2

Analyse des algorithmes

Analyser un algorithme revient à prévoir les ressources nécessaires à son

exécution. Les ressources pertinentes peuvent être diverses : la place mémoire,

la largeur de bande d’une communication, mais le plus souvent, on s’intéresse

au temps de calcul.

La complexité d’un algorithme est le temps et l’espace mémoire nécessaires

à son exécution. L’analyse de la complexité permet de comparer les algo-

rithmes indépendamment des langages de programmation et des machines

sur lesquelles ils doivent s’exécuter. On pourra dire qu’un algorithme est

meilleur qu’un autre pour des données de grande taille, ou bien qu’il est

optimal pour résoudre un type de problème.

2.1 Modèle de machine

Pour analyser la complexité des algorithmes, on doit expliciter le modèle

de machine utilisé pour l’exécution.

21

Un ordinateur est une machine disposant

1. d’une unité de calcul pour exécuter les opérations arithmétiques et

logiques.

2. d’une mémoire permettant le stockage des instructions et des données.

et on suppose les propriétés suivantes

– on a accès à un élément dans la mémoire en un temps fixe,

– l’unité de calcul ne peut traiter qu’une opération à la fois,

– le coût de transfert des informations est négligeable devant le coût des

opérations.

Il faut alors quantifier les grandeurs physiques que sont le temps d’exécution

et la place mémoire.

Pour un algorithme donnéA implémenté par un programme P et s’exécutant sur une machine M à partir de la donnée d, on exprime

– la complexité en temps en comptant le nombre d’opérations ef-

fectuées par le programme P, et en utilisant le nombre de cycles horloge nécessités par chaque opération sur la machine M.

– la complexité en espace en comptant le nombre de données d du

programme, le nombre d’informations supplémentaires pour manipuler

ces données, et en utilisant le nombre de mots mémoire nécessaires pour

stocker chacune d’elles dans la mémoire deM

22

2.2 Mesure de la complexité

Le temps d’exécution d’un algorithme dépend de la taille de son entrée.

Pour de nombreux problèmes, comme le tri, la mesure est le nombre d’éléments

constituant l’entrée, par exemple la longueur du tableau pour le tri. Pour

chaque algorithme analysé, la mesure utilisée pour la taille de l’entrée doit

être précisée.

Parfois on souhaite analyser un algorithme selon certaines opérations

jugées fondamentales. Par exemple, pour le tri par insertion, on compte les

comparaisons entre éléments et décalages d’éléments. Pour une multiplica-

tion de deux matrices, on compte les opérations entre les nombres (additions

et multiplications). On peut alors chercher des algorithmes optimaux selon

le nombre de ces opérations.

2.2.1 Mesure du coût d’un algorithme

On va donc associer un coût à chacune des opérations de l’algorithme, ce

coût pouvant représenter son temps d’exécution, l’espace mémoire nécessaire

supplémentaire ou son nombre d’opérations fondamentales.

Pour calculer le coût d’un algorithme, on utilise sa description en langage

algorithmique.

– Dans une structure de contrôle séquentielle, on ajoute les coûts des

diverses instructions.

– Dans une structure de contrôle conditionnelle, on exhibe un majorant

valable pour toutes les branches possibles de la structure.

23

EXEMPLE. Soit l’instruction

si C

alors I1

sinon I2

Si on note c(x) le coût de l’entité x, on aura

c(si C alors I1 sinon I2) ≤ c(C) + max{c(I1), c(I2)}

– dans une structure de contrôle itérative, on aura

i

c(bi)

où i compte les itérations, et où c(bi) désigne le coût de l’exécution

numéro i du corps de la boucle. Si le nombre de tours n’est pas connu

explicitement, on doit alors majorer cette grandeur.

2.2.2 Exemple du tri par insertion

Considérons toutes les opérations de l’algorithme et associons-leur un

coût correspondant à leur temps d’exécution. Chaque ligne i prendra alors

le temps ci où ci est une constante. Notons n la longueur du tableau. Pour

chaque j = 2, . . . n, on appelle tj le nombre de fois que le test de la boucle

tant que à la ligne 4 est exécuté pour cette valeur de j.

Coût Nombre fois TRI-INSERTION(A)

c1 n 1 pour j ←− 2 à longueur[A] c2 n− 1 2 faire cle ←− A[j] c3 n− 1 3 i←− j − 1

24

c4 ∑n

j=2 tj 4 tant que i > 0 et A[i] > cle

c5 ∑n

j=2(tj − 1)5 faire A[i + 1]←− A[i] c6

∑n j=2(tj − 1)6 i←− i− 1

c7 n− 1 7 A[i + 1]←− cle

On obtient la formule suivante pour la complexité de l’algorithme.

C(n) = c1n + c2(n− 1) + c3(n− 1) + c4 n ∑

j=2

tj + c5 n ∑

j=2

(tj − 1)

+c6 n ∑

j=2

(tj − 1) + c7(n− 1)

Cette formule peut être exploitée en la spécialisant selon certains cas

dépendant de la nature de l’entrée. Par exemple, si le tableau est déjà trié,

on effectue le test de la ligne 5 qu’une seule fois par élément, donc tj = 1

pour j = 2, . . . , n et le temps d’exécution devient une fonction linéaire de n.

C(n) = c1n + c2(n− 1) + c3(n− 1) + c4(n− 1) + c7(n− 1)

= (c1 + c2 + c3 + c4 + c7)n + (c2 + c3 + c4 + c7)

Généralement, la complexité est etudiée dans le meilleur cas, le pire des

cas, ou en moyenne. De plus, ce sont les ordres de grandeur des formules

(quand la taille des données est très grande) qui nous renseignent le mieux.

Si le tableau est trié en ordre inverse, il s’agit du cas le pire. À ce moment-

là, tj = j pour j = 2, . . . , n. En utilisant les identités suivantes

n ∑

j=2

j = n(n + 1)

2 − 1,

n ∑

j=2

j − 1 = n(n− 1) 2

(2.1)

on obtient la fonction quadratique de n suivante (les coûts sont considérés

comme des constantes).

25

C(n) = c1n + c2(n− 1) + c3(n− 1) + c4 (

n(n + 1)

2 − 1

)

+c5

(

n(n− 1) 2

)

+ c6

(

n(n− 1) 2

)

+ c7(n− 1)

= (

c4 2

+ c5 2

+ c6 2

)

n2 + (

c1 + c2 + c3 + c4 2

+ c5 2

+ c6 2

+ c7

)

n

−(c2 + c3 + c4 + c7)

2.2.3 Fonctions et procédures récursives

Dans le cas de fonctions récursives, on est confrontés à la résolution

d’équations récurrentes. Le coût C(n) d’un algorithme récursif pour une donnée de taille n s’écrit selon la méthode récursive en fonction de f(k)

pour k < n.

Exemple 1

n!

FACTORIELLE(n)

c1 si n = 0

alors

c2 retourner 1

sinon

c3 retourner n * factorielle(n-1)

Calculons le coût de l’algorithme en fonction de n.

26

C(0) = c1 + c2 C(n) = c1 + f(n− 1) + c3, si n ≥ 1

On a immédiatement

C(n) = (n + 1)c1 + c2 + nc3

Complexité en temps. Considérons que la complexité en temps que nous

noterons T (n) ne dépend que du nombre de multiplications effectuées. Dans

ce cas, on pose

c1 = 0

c2 = 0

c3 = 1

Ce qui donne

T (n) = n

L’algorithme est bien linéaire en temps d’exécution. Un calcul similaire sur

l’algorihme itératif de la factorielle donnerait exactement le même résultat.

Complexité en espace. En ce qui concerne la complexité en espace mémoire,

que nous noterons M(n), elle est donnée par la formule

M(n) = m + C(n)

où m représente l’espace mémoire nécessaire pour stocker les données d’entrée,

et les coûts de la fonction f sont associés à la place mémoire supplémentaire

nécessaire pour l’exécution de chaque instruction. Nous avons donc les coûts

27

suivants, en nombre d’unités mémoire pour stocker un entier.

c1 = 0

c2 = 0

c3 = 1

m = 1

La complexité en espace de la fonction est alors donnée par la formule

M(n) = n + 1

Remarque. Nous avons supposé dans ces calculs que chaque entier est

stocké dans un espace mémoire de même taille. Alors, les opérations sur ces

entiers (stockage, lecture et multiplication) sont d’un coût constant. Cette

supposition est très réductrice en pratique puisque dans un espace mémoire

donné, on ne peut coder qu’un nombre fini d’entiers. Une borne supérieure

peut alors être exhibée pour la complexité. Si l’on considère, par contre, que

la taille des entiers dépend de leur valeur (par exemple, log2n bits pour la

valeur n), les opérations associées aux entiers ne sont plus d’un coût constant

mais dépendent de la valeur de l’entier. Ces coûts entrent en jeu dans le calcul

de la complexité qui n’est alors plus du tout la même.

Effectuons, à titre de comparaison le même calcul sur l’algorihme itératif

(avec les mêmes suppositions). La boucle pour comporte plusieurs opérations

qu’il est nécessaire de dissocier. Nous associons le coût c2 à l’opération d’ini-

tialisation de la boucle (qui ne s’effectue qu’une seule fois), le coût c3 au test

de la boucle (qui s’effectue n + 1 fois) et c4 à l’opération d’incrémentation

(qui s’effectue n fois).

FACTORIELLE-ITERATIVE(n)

28

c1 r ←1 c2 pour i ←n à 1 par pas de -1% Initialisation c3 % Test

c4 % Incrémentation

c5 r ←r * i c6 retourner r

Dans le cas de cet algorithme nous avons

M(n) = m + c1 + c2 + (n + 1)c3 + nc4 + nc5 + c6

Afin de calculer la complexité en espace mémoire, on peut utiliser les valeurs

de coûts suivantes.

c1=1 Place de r

c2=1 Place de i

c3=0

c4=0

c5=0

c6=0

m=1 Place de n

Alors, on obtient

M(n) = 1 + 1 + 1 = 3

Ce qui confirme que la fonction factorielle récursive a une complexité en

espace mémoire linéaire et égale à la valeur de son entrée, alors que la fonction

itérative a une complexité constante.

29

Exemple 2

Soit un problème de taille n que l’on subdivise en a sous-problèmes de

tailles n b . Pour simplifier, supposons qu’un sous-problème de taille 1 a une

complexité unitaire, et que la combinaison d’assemblage des solutions des

sous-problèmes pour résoudre le problème de taille n est d(n).

On peut alors écrire :

C(1) = 1

C(n) = aC(n b ) + d(n)

En substituant de proche en proche, on aboutit à la relation :

C(n) = aiC( n

bi ) +

i−1 ∑

j=0

ajd( n

bj )

On suppose qu’il existe k tel que n bk

= 1 (et donc k = logbn). k représente

le nombre d’itérations nécessaire pour atteindre le cas unitaire à partir de n.

Remplaçons i par k et C(1) par 1. On obtient :

C(n) = ak + k−1 ∑

j=0

ajd(bk−j) = nlogba + k−1 ∑

j=0

ajd(bk−j)

car ak = alogbn = nlogba.

Durée : 1H30

2.2.4 Configuration des données et complexité

EXEMPLE. Recherche séquentielle d’un élément dans un tableau.

On se donne un vecteur v à n éléments et on veut savoir si un élément d

donné appartient à v ou pas.

RECHERCHE-ELEMENT-TABLEAU(v)

30

commentaires (0)
Aucun commentaire n'a été pas fait
Écrire ton premier commentaire
Ceci c'est un aperçu avant impression
3 shown on 32 pages
Télécharger le document