begin process at 2012 02 12 10:17:41
  Trouver un code source :
 
dans
 
Accueil > 

Tutoriels

 > 

Maths & Algorithmes

 > LA TECHNIQUE DES SENTINELLES

LA TECHNIQUE DES SENTINELLES


 Information sur le tutoriel

Note :
8 / 10 - par 1 personne
8,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10


 Description

Cette technique de programmation permet d'économiser des instructions dans plusieurs algorithmes classiques de manipulation de données.

Tutorial

Cette technique de programmation permet d'économiser des instructions dans plusieurs algorithmes classiques de manipulation de données.


Une instruction en langage évolué (C ou autre) est une suite de plusieurs instructions en langage machine (assembleur). Gagner des instructions dans un algorithme, c'est gagner plusieurs instructions machines, c'est-à-dire de nombreux cycles d'exécution d'un algorithme.

 

1) Algorithme de base

 

Voici un algorithme de recherche d'une clé x dans un tableau a[] de quatre éléments non triés :

 

for ( i = 0,trouve = 0 ; i < 4 && !trouve; i++)

            if ( a[i] == x ) trouve = 1;

 

Cette version n'est pas très efficace :

 

- On réalise 2 initialisations (2 instructions) ;

- On réalise 2 tests (2 instructions) avant chaque passage dans la boucle ( i < 4 et trouve != 0)

 

2) Algorithme amélioré

 

Une version un peu plus travaillée de cet algorithme est :

 

for ( i = 0;i < 4; i++)

            if ( a[i] == x ) i = 5;

trouve = (i == 5);

 

On gagne :

 

- 1 initialisation (1 instruction) en début d'algorithme;

- 1 test (1 instruction) avant chaque passage de boucle.Soit n instructions sur un tableau de n éléments (dans le meilleur des cas).

 

3) Algorithme optimisé

 

En retravaillant un peu l'algorithme, on peut réduire encore le nombre d'instructions :

 

i = 0 ;

while ( i< 4 && (a[i] != x) ) i++ ;

trouve = (i < 4 );

 

Ici on gagne juste une instruction : une affectation (i = 5). C est toujours ça...

 

4) Algorithme avec sentinelle

 

Enfin, on peut exécuter l'algorithme sans tester l'indice de boucle. Il suffit de prévoir une case de travail, où l'on place la clé x pour être sûr de la trouver. Cette case s'appelle une sentinelle.

  

a  =  | 4 | 3 | 2 | 5 | x |

 

On peut aussi voir les sentinelles comme des éléments butoirs dans l'exécution d'un algorithme.

 

a[4] = x ; // sentinelle

i = 0 ;

while (a[i] != x ) i++ ;

trouve = (i < 4) ;

 

En éliminant le test de l'indice de boucle, on gagne encore n instructions sur un tableau de n éléments (dans le meilleur des cas).

 

C'est-à-dire que par rapport à l?algorithme de base, on a gagné jusqu'à 2n + 2 instructions.

 

Avec un tableau de 4 éléments, l?économie en instructions est insignifiante, mais avec des tableaux de plusieurs milliers ou million de cellules, l'économie est de plusieurs milliers ou plusieurs millions d?instructions gagnées.

 

Dans le cas où la recherche se fait en sens inverse, onplace la sentinelle au début du tableau.

Dans le cas où l'on ne sait pas dans quel sens se fera la recherche on crée un tableau avec deux sentinelles, une en début de tableau et une en fin de tableau.

 

Les sentinelles sont utilisables avec les tableaux, leslistes, les arbres et d'autres structures de données.

 

Un autre exemple d'algorithme utilisant une sentinelle : http://www.cppfrance.com/codes/TRI-INSERTION-AVEC-SENTINELLE_37794.aspx

 Historique

17 août 2006 22:44:55 :
Correction du bug de l'editbox de cette partie du site (les tutoriaux). Ca fait plusieurs fois que je me fais piégé. Le copier coller n'a pas marché (mots collés, apostrophes remplacées par des ?, mises en forme initiale non respectée...). Si Nix passe par là, il faudra faire quelquechose...

Commentaires

Commentaire de RemiONERA le 05/06/2007 09:27:25

Technique tout à fait intéressante. Juste une remarque je ne comprends pas bien la finalité du 4ème point

a[4] = x ; // sentinelle

i = 0 ;

while (a[i] != x ) i++ ;

trouve = (i < 4) ;

Sauf erreur de ma part dans cet exemple trouve sera toujours faux ne manque t'il pas un test dans le while?

Commentaire de AlexN le 05/06/2007 21:13:42

Cet algorithme fonctionne correctement.




L'astuce est que l'on place la valeur à rechercher dans une case du tableau (la première ou la dernière) qui est réservée à cet usage et qui ne peut pas contenir de vraies valeurs du tableau.
Ainsi même si la valeur n'existe pas dans le tableau, la recherche sera stoppée par la sentinelle - qui contient la valeur cherchée.

Si valeur x n'existe pas dans le tableau, alors, en fin de boucle de recherche, l'indice i est au delà des bornes d'éléments valides du tableau. On sait que x n'est pas dans le tableau.
Si la valeur x existe dans le tableau alors la recherche s'est arrêtée et l'indice i pointe un élément dans le tableau. On sait que la valeur x est dans le tableau et on a l'indice de sa première ou dernière position.

a[4] = x ; // initialisation de la case sentinelle avec la valeur recherchée
i = 0 ; //  initialisation de l'indice de recherche
while (a[i] != x) i++ ; // recherche de la valeur x (qui est au moins en fin de tableau, dans la case sentinelle)
trouve = (i<4); // test d'appartenance

Note : L'algorithme fonctionne dans les deux sens, il faut cependant adapter le tableau

a[0] = x; // initialisation de la case sentinelle avec la valeur recherchée
i = 4; // tableau de 4 éléments + 1 case sentinelle
while (a[i] != x) i--; // recherche de la valeur x
trouve = (i > 0); // test d'appartenance

Commentaire de Kane TWD le 25/06/2007 15:25:46

Juste une question au passage...

Est-ce que tu connais le concept de recherche dichotomique ?

Si non
tu devrais te renseigner.... tu va aimer.

Commentaire de AlexN le 25/06/2007 20:34:52

Recherche dichotomique ?
Voyons voyons... il doit s'agir d'un algorithme qui ne fonctionne QUE sur des tables TRIEES.
L'algorithme qui est sur cette page, et que tu n'as pas lu ou pas compris, fonctionne sur TOUTES les tables.

sinon relis tes cours ou écoutes mieux tes profs... tu vas apprendre. :o)

Commentaire de le_duche le 22/03/2008 02:13:05

Sympa l'idée, mais ça ne fait pas gagner de complexité... Donc j'aime, mais je ne prendrai jamais la peine de me casser la tête comme ça ^_^

Commentaire de reveurduciel le 27/01/2009 15:26:48

Tutoriel très intéressant.

Merci beaucoup :)

Commentaire de ATitus le 09/02/2010 22:04:41

je ne connais pas trop le C, mais ce tutorial est interressant .

Il doit etre possible d'adapter sur d'autres langages.

@ +

Commentaire de jcthomas71 le 18/10/2011 01:43:55

Bonjour,

Je ne connaissais pas la technique des sentinelles, mais il me semble que votre présentation n'en soit pas très rigoureuse car elle est confuse.

En effet je vais m'expliquer dans le même ordre avec laquelle vous avez présenté les choses.

1)Votre premier algorithme que vous présentez comme exemple pour montrer l'utilité de votre technique par du principe que vous connaissez initialement le nombre de d'élements que contient votre tableau (normalement, ce fait représente une instruction supplémentaire pour en connaître la valeur).
2) jusqu'à la fin de la 3e partie, vos optimisations de rigueur d'optimisations n'incluent aucune notion de sentinelle. Donc jusque la, on n'en voie pas l'intérêt par voie de conséquence.
3)Ensuite à partir du 4 vous justifiez l'intérêt de la sentinelle comme étant un moyen de ne pas tester l'indice de boucle, vu que vous la qualifier "d'indice butoir". C'est la que votre raisonnement devient confus.
Je m'explique.
A) Il n'y a aucun intérêt à rajouter un indice butoir à un tableau pour ne pas en tester les limites quand d'une part elle est connue préalablement au test et qu'on en utilise la valeur conjointement à votre sentinelle au sein du même algorithme. Du coup non seulement votre algorithme ne démontre rien mais il en devient inutile.
B) D'autre part l'inutilité de votre sentinelle va bien plus loin que cela. En effet, en partant du principe que la valeur que l'on recherche au sein du tableau est unique et qu'on la rajoute à la fin du tableau, comme dit précédemment, outre le fait qu'en tant que valeur butoir, ce placement reste inutile car la dimension maximum est connue et utilisée dans l'algorithme de part ailleurs), il se produit l'effet indésirable (lorsque la valeur recherchée est bien présente dans le tableau), que l'algorithme tel que présenté ici est incapable de dire si la valeur trouvée est celle recherchée ou la sentinelle. La conséquence à ceci est loin d'être négligeable, car on ne peut dire, malgré que l'algorithme ait trouvé la valeur recherchée, si la valeur est présente ou non dans le tableau. Et moi, en ce qui me concerne, je suis capable d'économiser encore n instructions pour arriver au même résultat que vous.
C)La seule chose que je vous concède quand à l'intérêt d'une telle technique, que vous n'avez pas exposé ici, c'est que l'execution d'un a.push('@@') par exemple '@@' étant la sentinelle, malgré le fait qu'elle constitue toujours en soit une instruction au même titre qu'un b=a.length, c'est qu'elle ne cache aucun comptage sous-jacent des dimensions du tableau concerné et qui reste par conséquent plus performant.

En résumé, j'espère que cette technique inutile n'est pas enseignée en supérieur, ou alors vous n'y avez rien compris ou vous n'avez pas su l'expliquer correctement.

Cordialement,    

Jean-Christophe

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,593 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales