Je recherche une implémentation .NET d'une file d'attente prioritaire ou d'une structure de données de tas
Les files d'attente prioritaires sont des structures de données qui offrent plus de flexibilité qu'un simple tri, car elles permettent à de nouveaux éléments d'entrer dans un système à des intervalles arbitraires. Il est beaucoup plus rentable d'insérer un nouveau travail dans une file d'attente prioritaire que de tout trier à chaque arrivée.
La file d'attente prioritaire de base prend en charge trois opérations principales:
- Insérez (Q, x). Étant donné un élément x avec la clé k, insérez-le dans la file d'attente prioritaire Q.
- Find-Minimum (Q). Renvoie un pointeur sur l'élément dont la valeur de clé est inférieure à toute autre clé de la file d'attente prioritaire Q.
- Supprimer-Minimum (Q). Supprimer l'élément de la file d'attente prioritaire Q dont la clé est minimale
À moins que je ne regarde au mauvais endroit, il n'y en a pas dans le cadre. Quelqu'un en connaît-il un bon ou dois-je rouler le mien?
c#
.net
data-structures
heap
priority-queue
Doug McClean
la source
la source
Réponses:
J'aime utiliser les classes
OrderedBag
etOrderedSet
dans PowerCollections comme files d'attente prioritaires.la source
Vous pourriez aimer IntervalHeap de la bibliothèque de collections génériques C5 . Pour citer le guide d'utilisation
L'API est assez simple
Installer depuis Nuget https://www.nuget.org/packages/C5 ou GitHub https://github.com/sestoft/C5/
la source
Voici ma tentative d'un tas .NET
Quelques tests:
la source
IEqualityComparer<T>
ne serait pas suffisant, car cela ne vous dirait que si deux éléments sont égaux, alors que vous devez connaître la relation entre eux (qui est plus petit / plus grand). C'est vrai que j'aurais pu utiliserIComparer<T>
cependant ...voici celui que je viens d'écrire, peut-être qu'il n'est pas aussi optimisé (utilise simplement un dictionnaire trié) mais simple à comprendre. vous pouvez insérer des objets de différents types, donc pas de files d'attente génériques.
la source
J'en ai trouvé un par Julian Bucknall sur son blog ici - http://www.boyet.com/Articles/PriorityQueueCSharp3.html
Nous l'avons légèrement modifié afin que les éléments de faible priorité dans la file d'attente finissent par "remonter" au sommet au fil du temps, afin qu'ils ne souffrent pas de la famine.
la source
Comme mentionné dans Microsoft Collections pour .NET , Microsoft a écrit (et partagé en ligne) 2 classes PriorityQueue internes dans le .NET Framework. Leur code est disponible pour essayer.
EDIT: Comme l'a commenté @ mathusum-mut, il y a un bogue dans l'une des classes PriorityQueue internes de Microsoft (la communauté SO a, bien sûr, fourni des correctifs pour cela): Bogue dans PriorityQueue interne de Microsoft <T>?
la source
PriorityQueue<T>
dans la source partagée de Microsoft sont marquées avecinternal
un spécificateur d'accès. Ils ne sont donc utilisés que par les fonctionnalités internes du framework. Ils ne sont pas disponibles pour une consommation générale simplement en se référantwindowsbase.dll
à un projet C #. La seule façon est de copier la source partagée dans le projet lui-même à l'intérieur d'un fichier de classe.Vous pouvez trouver utile cette implémentation: http://www.codeproject.com/Articles/126751/Priority-queue-in-Csharp-with-help-of-heap-data-st.aspx
il est générique et basé sur la structure de données du tas
la source
facile.
la source
for (var n2 = n / 2; n > 0 && comparer.Compare(v, heap[n2]) > 0; n = n2, n2 /= 2) heap[n] = heap[n2];
et je me demande si ça valait la peine d'êtreUtilisez un traducteur Java vers C # sur l'implémentation Java (java.util.PriorityQueue) dans le cadre des collections Java, ou utilisez plus intelligemment l'algorithme et le code principal et branchez-le dans une classe C # de votre propre fabrication qui adhère au cadre des collections C # API pour les files d'attente, ou au moins les collections.
la source
AlgoKit
J'ai écrit une bibliothèque open source appelée AlgoKit , disponible via NuGet . Il contient:
Le code a été largement testé. Je vous recommande vraiment de l'essayer.
Exemple
Pourquoi ces trois tas?
Le choix optimal d'implémentation dépend fortement des entrées - comme le montrent Larkin, Sen et Tarjan dans A back-to-basics empirical study of priority queues , arXiv: 1403.0252v1 [cs.DS] . Ils ont testé des tas de d-aire implicites, des tas de pairage, des tas de Fibonacci, des tas binomiaux, des tas de d-aire explicites, des tas d'appariement de rang, des tas de tremblement de terre, des tas de violation, des tas de faible relâchement de rang et des tas de Fibonacci stricts.
AlgoKit propose trois types de tas qui semblaient être les plus efficaces parmi ceux testés.
Indice sur le choix
Pour un nombre relativement restreint d'éléments, vous seriez probablement intéressé à utiliser des tas implicites, en particulier des tas quaternaires (implicites à 4 aires). En cas d'opération sur de plus grandes tailles de tas, les structures amorties comme les tas binomiaux et les tas d'appariement devraient mieux fonctionner.
la source
Voici une autre implémentation de l'équipe NGenerics:
NGenerics PriorityQueue
la source
J'ai eu le même problème récemment et j'ai fini par créer un package NuGet pour cela.
Cela implémente une file d'attente prioritaire basée sur le tas standard. Il a également toutes les subtilités habituelles des collections BCL:
ICollection<T>
et l'IReadOnlyCollection<T>
implémentation, leIComparer<T>
support personnalisé , la possibilité de spécifier une capacité initiale, et unDebuggerTypeProxy
de rendre la collection plus facile à utiliser dans le débogueur.Il existe également une version en ligne du package qui installe simplement un fichier .cs unique dans votre projet (utile si vous voulez éviter de prendre des dépendances visibles de l'extérieur).
Plus d'informations sont disponibles sur la page github .
la source
Une implémentation simple du tas max.
https://github.com/bharathkumarms/AlgorithmsMadeEasy/blob/master/AlgorithmsMadeEasy/MaxHeap.cs
la source
L'implémentation suivante d'une
PriorityQueue
utilisationSortedSet
de la bibliothèque système.la source
T x
etK key
? Je suppose que c'est une astuce pour autoriser la duplicationT x
, et j'ai besoin de générer une clé unique (par exemple UUID)?