Vous êtes sur la page 1sur 4

- Conception et analyse dalgorithmes -

Diviser pour Rgner : Recherche Dichotomique


TD4 1re anne ESIEA - Semestre 2
L. Beaudoin & R. Erra & A. Gademer & L. Avanthey & B. Larroque 2011 -2012

Avant propos
La mthode Diviser pour Rgner est une stratgie aussi rpandue quecace. Nous allons voir une de ses implmentations la plus simple : la dichotomie.

Problme : Recherche dichotomique dans un ensemble tri


Dichotomie : La dichotomie ( couper en deux en grec) est une stratgie algorithmique de la catgorie Diviser pour Rgner . Cest un processus itratif ou rcursif o, chaque tape, on dcoupe lespace de recherche en deux parties (pas forcement gale) puis ayant dtermin dans laquelle se trouve la solution, on restreint lespace cette partie.

Mthode du dictionnaire Un exemple courant de recherche dichotomique consiste consulter lannuaire ou le dictionnaire : on louvre approximativement au milieu, si le nom recherch est situ aprs dans lalphabet que le nom situ sur la page, on recherche plus loin, sinon on recherche plus avant, en rduisant lespace de R recherche un ensemble de plus en plus petit de pages (bien quon nisse le plus souvent par une recherche linaire, nom par nom )R

1.1

Fonctions auxiliaires

EXERCICE 1
1 10 01 1 10 10

Extrayez des TP prcdents (ou recodez) les fonctions de remplissage de tableau 1D partir du ux standard (loadArray) et dachage du tableau (showArray). Ces fonctions auront pour prototypes :
void loadArray(int size, int iArray[size]) void showArray(int size, int iArray[size])

Diviser pour Rgner : Recherche Dichotomique EXERCICE 2


1 10 01 1 10 10

TD4

Crez un programme qui : Rcupre un entier strictement positif (> 0) au clavier, Dclare un tableau dentier dont la taille correspond au nombre rcupr, Remplis le tableau avec la fonction loadArray, Ache le tableau avec showArray (les nombres sont spars par une espace). EXERCICE 3
1 10 01 1 10 10

crivez la fonction :
int isSorted(int size, int iArray[size])

Cette fonction itrative renvoie 1 (vrai) si le tableau pass en paramtre est tri dans lordre croissant et 0 (faux) sinon. Testez votre fonction en lajoutant votre main.

1.2

Recherche dichotomique

QUESTION 1 Imaginez lalgorithme permettant de reproduire la mthode du dictionnaire pour retrouver lindice dun lment dans un tableau tri.

Indice n1 La mthode dichotomique doit permettre de rduire lespace de recherche chaque tape, on peut donc dnir une borne gauche (lowerBound) et une borne droite (upperBound) variables qui correspondent au indice minimum et maximum de notre espace de recherche cest--dire la portion de tableau que lon est en train de traitLa mthode dichotomique doit permettre de rduire lespace de recherche chaque tape, on peut donc dnir une borne gauche (lowerBound) et une borne droite (upperBound) variables qui correspondent au indice minimum et maximum de notre espace de recherche cest--dire la portion de tableau que lon est en train de traiterer.

Indice n2 Quelles sont les conditions darrt de lalgorithme ? Que se passe-t-il si llment nest PAS prsent dans le tableau ? EXERCICE 4
1 10 01 1 10 10

crivez la fonction :
int binarySearchIter(int size, int iArray[size], int seeked)

Cette fonction itrative recherche de manire dichotomique llment seeked dans le tableau et renvoie soit lindice de la case qui contient cette valeur, soit -1 si la valeur ne sy trouve pas.

Diviser pour Rgner : Recherche Dichotomique

TD4

Indice n3 Faites attention aux cas particuliers. Nhsitez pas revenir sur votre algorithme si les tests empiriques vous font dcouvrir des situations que vous naviez pas anticipes.

Correction Le correcteur automatique valide votre fonction en trois tapes : - dtection des fuites mmoires - validation des sorties de la fonction (plusieurs rponses possibles) - validation de lalgorithme par mesure du nombre dinstructions EXERCICE 5
1 10 01 1 10 10

Testez votre fonction en compltant votre programme. Il doit dsormais : Rcuprer un entier strictement positif (> 0) au clavier, Dclarer un tableau dentier dont la taille correspond au nombre rcupr, Remplir le tableau avec la fonction loadArray, Acher le tableau avec showArray (les nombres sont spars par une espace). Vrier si le tableau est tri (et quitte avec le message "Array is not sorted !" dans le cas contraire), puis tant quil y a des entiers signs sur le ux dentre rcuprer (par une recherche dichotomique) lindice du nombre dans le tableau (ou -1 si celui-ci ny est pas), Acher "XX is not in the array." ou "XX can be found at index YY." o XX est le nombre recherch et YY lindice o il se trouve.

EXERCICE 6
1 10 01 1 10 10

crivez la fonction :
int binarySearchRec_aux(int size, int iArray[size], int lowerBound, int upperBound, int seeked)

Cette fonction rcursive recherche de manire dichotomique llment seeked dans le tableau et renvoie soit lindice de la case qui contient cette valeur, soit -1 si la valeur ne sy trouve pas. Lors de lappel initial les bornes sont xes 0 et (size 1). EXERCICE 7
1 10 01 1 10 10

crivez ensuite la fonction :


int binarySearchRec(int size, int iArray[size], int seeked)

Cette fonction encapsule la prcdente en initialisant les bornes correctement.

Diviser pour Rgner : Recherche Dichotomique

TD4

Problme : Devine mon secret

Vous avez probablement dj jou ce petit jeu :le joueur 1 pense un nombre secret entre 1 et 100, puis le joueur 2 fait des propositions auquel le joueur 1 rpond soit "plus", soit "moins", soit "trouv". On peut corser le jeu en limitant le nombre maximum de proposition et/ou en augmentant lespace de recherche. Nous considrerons ici un programme EXISTANT guessMyNumber qui tient le rle du joueur 1 : il tire alatoirement un nombre en 0 et (263 1) et lit sur lentre standard des propositions auquel il rpond par + , - ou = . Pouvez-vous trouver le nombre secret en moins de 64 itrations ? EXERCICE 8 (D ludique)
1 10 01 1 10 10

crivez le programme qui : propose un nombre sur la sortie standard (printf), suivi dun retour la ligne et de la commande fflush :
printf("%llu\n", proposal); fflush(stdout); // Needed for inter-program communication

lit sur lentre standard un caractre (utilisez la notation " %c" avec un espace AVANT le descripteur pour liminer les caractres spciaux) analyse ce caractre ( + , - ou = ) et ragit en fonction (i.e. propose un nouveau nombre). Votre programme sarrtera si : si scanf renvoie autre chose que 1, si le caractre reu est = , si il ny a plus dautre possibilit (lespace de recherche est rduit 1 seule valeur).

guessMyNumber Vous trouverez le code source du programme guessMyNumber ainsi que le script dexcution sur le blog pour pouvoir tester votre programme.

Mmos Lorsque lon recherche une information et que lon possde une relation dordre (plus petit ou plus grand), la recherche dichotomique est la mthode la plus rapide.