Il existe cette structure de données qui échange les performances de l'accès aux baies contre la nécessité de les itérer lors de leur effacement. Vous gardez un compteur de génération à chaque entrée, ainsi qu'un compteur de génération global. L'opération "clear" augmente le compteur de génération. Sur chaque accès, vous comparez les compteurs de génération locaux et globaux; s'ils diffèrent, la valeur est traitée comme "propre".
Cela est apparu récemment dans cette réponse sur Stack Overflow , mais je ne me souviens pas si cette astuce a un nom officiel. Le fait-il?
Un cas d'utilisation est l'algorithme de Dijkstra si seulement un petit sous-ensemble des nœuds doit être assoupli, et si cela doit être fait à plusieurs reprises.
algorithms
terminology
krlmlr
la source
la source
Réponses:
L'approche susmentionnée nécessite que chaque cellule soit capable de contenir un nombre suffisamment grand pour contenir le nombre de fois que la matrice peut avoir besoin d'être réinitialisée, ce qui représente une pénalité d'espace substantielle. Si un slot est capable de contenir au moins une valeur qui ne sera jamais légitimement écrite, on peut éviter d'avoir une autre pénalité d'espace (non constante) au détriment de l'ajout d'une
O(Wlg(N))
pénalité de temps, oùW
est le nombre de slots de tableau distincts écrits entre opérations de suppression etN
correspond à la taille du tableau. Par exemple, supposons que l'on stocke des entiers de -2 147 483 647 à 2 147 483 647 (mais jamais -2 147 483 648) et que l'on souhaite que les éléments de tableau vides soient lus comme des zéros. Commencez par remplir le tableau avec -2 147 483 648 (appelez cette valeurB
). Lors de la lecture d'un emplacement de baie pour l'application, indiquez une valeurB
égale à zéro. Avant d' écrire fente de réseauI
, vérifier si elle lieuB
et si oui , etI
est supérieur à un, stocker un zéro à fenteI/4
après avoir effectué un contrôle similaire pour cet emplacement (et, si elle lieuB
,I/16
etc.).Pour effacer le tableau, commencez par
I
égal à 0 ou 1, selon la base du tableau (l'algorithme tel que décrit fonctionnera pour l'un ou l'autre). Répétez ensuite la procédure suivante: Si itemI
estB
, incrémentezI
et, si cela donne un multiple de quatre, divisez par quatre (terminez si la division donne une valeur de 1); si l'élémentI
ne l'est pasB
, stockezB
-le et multipliez-leI
par quatre (s'ilI
commence à zéro, la multiplication par quatre le laissera à zéro, mais puisque l'élément 0 sera vide,I
sera incrémenté).Notez que l'on pourrait remplacer la constante "quatre" ci-dessus par d'autres nombres, avec des valeurs plus grandes nécessitant généralement moins d'étiquetage de travail, mais des valeurs plus petites nécessitant généralement moins d'effacement de travail; comme les emplacements de tableau marqués doivent être effacés, une valeur de trois ou quatre est presque certainement optimale; comme la valeur quatre est certainement proche de l'optimale, meilleure que deux ou huit, et plus pratique que n'importe quel autre nombre, cela semble le choix le plus raisonnable.
la source
Je l'appellerais "réinitialisation de cellule de tableau paresseux", mais il ne semble pas avoir de nom établi (c'est-à-dire que le nom est largement utilisé).
L'algorithme est intelligent, mais très spécialisé et applicable dans un domaine très étroit.
la source
Je crois que c'est un cas particulier de mémorisation , sauf dans ce cas, les "mémos" implicitement "vieillissent" à chaque incrément du compteur global. J'imagine une sorte de "mémorisation à l'envers".
la source