Ich suche nach einer .NET-Implementierung einer Prioritätswarteschlange oder einer Heap-Datenstruktur
Prioritätswarteschlangen sind Datenstrukturen, die mehr Flexibilität bieten als einfaches Sortieren, da sie es neuen Elementen ermöglichen, in beliebigen Intervallen in ein System einzutreten. Es ist viel kostengünstiger, einen neuen Job in eine Prioritätswarteschlange einzufügen, als bei jeder Ankunft alles neu zu sortieren.
Die Warteschlange mit grundlegender Priorität unterstützt drei primäre Vorgänge:
- Einfügen (Q, x). Fügen Sie ein Element x mit dem Schlüssel k in die Prioritätswarteschlange Q ein.
- Find-Minimum (Q). Geben Sie einen Zeiger auf das Element zurück, dessen Schlüsselwert kleiner als jeder andere Schlüssel in der Prioritätswarteschlange Q ist.
- Delete-Minimum (Q). Entfernen Sie das Element aus der Prioritätswarteschlange Q, dessen Schlüssel minimal ist
Wenn ich nicht am falschen Ort suche, gibt es keinen im Rahmen. Ist jemandem ein guter bekannt, oder sollte ich meinen eigenen rollen?
c#
.net
data-structures
heap
priority-queue
Doug McClean
quelle
quelle
Antworten:
Ich verwende gerne die Klassen
OrderedBag
undOrderedSet
in PowerCollections als Prioritätswarteschlangen.quelle
Möglicherweise gefällt Ihnen IntervalHeap aus der C5 Generic Collection Library . Um das Benutzerhandbuch zu zitieren
Die API ist einfach genug
Installieren Sie von Nuget https://www.nuget.org/packages/C5 oder GitHub https://github.com/sestoft/C5/
quelle
Hier ist mein Versuch, einen .NET-Heap zu erstellen
Einige Tests:
quelle
IEqualityComparer<T>
würde nicht ausreichen, da dies nur Aufschluss darüber gibt, ob zwei Elemente gleich sind, während Sie die Beziehung zwischen ihnen kennen müssen (wer ist kleiner / größer). Es ist wahr, dass ich hätte verwenden könnenIComparer<T>
...Hier ist eine, die ich gerade geschrieben habe. Vielleicht ist sie nicht so optimiert (verwendet nur ein sortiertes Wörterbuch), aber einfach zu verstehen. Sie können Objekte verschiedener Art einfügen, also keine generischen Warteschlangen.
quelle
Ich habe einen von Julian Bucknall in seinem Blog hier gefunden - http://www.boyet.com/Articles/PriorityQueueCSharp3.html
Wir haben es leicht modifiziert, damit Elemente mit niedriger Priorität in der Warteschlange im Laufe der Zeit nach oben "sprudeln", damit sie nicht verhungern.
quelle
Wie in Microsoft Collections for .NET erwähnt , hat Microsoft zwei interne PriorityQueue-Klassen geschrieben (und online freigegeben) in .NET Framework . Ihr Code steht zum Ausprobieren zur Verfügung.
BEARBEITEN: Wie @ mathusum-mut kommentierte, gibt es einen Fehler in einer der internen PriorityQueue-Klassen von Microsoft (die SO-Community hat natürlich Korrekturen dafür bereitgestellt): Fehler in der internen PriorityQueue <T> von Microsoft?
quelle
PriorityQueue<T>
in der gemeinsam genutzten Quelle von Microsoft mit eineminternal
Zugriffsspezifizierer gekennzeichnet sind . Sie werden also nur von den internen Funktionen des Frameworks verwendet. Sie sind nicht für den allgemeinen Verbrauch verfügbar, wenn Sie nur aufwindowsbase.dll
ein C # -Projekt verweisen . Die einzige Möglichkeit besteht darin, die freigegebene Quelle innerhalb einer Klassendatei in das Projekt selbst zu kopieren.Diese Implementierung kann nützlich sein: http://www.codeproject.com/Articles/126751/Priority-queue-in-Csharp-with-help-of-heap-data-st.aspx
Es ist generisch und basiert auf der Heap-Datenstruktur
quelle
einfach.
quelle
for (var n2 = n / 2; n > 0 && comparer.Compare(v, heap[n2]) > 0; n = n2, n2 /= 2) heap[n] = heap[n2];
Verwenden Sie einen Java to C # -Übersetzer für die Java-Implementierung (java.util.PriorityQueue) im Java Collections-Framework oder verwenden Sie den Algorithmus und den Kerncode intelligenter und fügen Sie ihn in eine eigene C # -Klasse ein, die dem C # Collections-Framework entspricht API für Warteschlangen oder zumindest Sammlungen.
quelle
AlgoKit
Ich habe eine Open-Source-Bibliothek namens AlgoKit geschrieben , die über NuGet verfügbar ist . Es beinhaltet:
Der Code wurde ausgiebig getestet. Ich empfehle Ihnen auf jeden Fall, es zu versuchen.
Beispiel
Warum diese drei Haufen?
Die optimale Wahl der Implementierung hängt stark von der Eingabe ab - wie Larkin, Sen und Tarjan in einer empirischen Studie zu Prioritätswarteschlangen zeigen , arXiv: 1403.0252v1 [cs.DS] . Sie testeten implizite D-Ary-Heaps, Pairing-Heaps, Fibonacci-Heaps, Binomial-Heaps, explizite D-Ary-Heaps, Rang-Pairing-Heaps, Beben-Heaps, Verstoß-Heaps, rangentspannte schwache Heaps und strenge Fibonacci-Heaps.
AlgoKit bietet drei Arten von Haufen, die unter den getesteten am effizientesten zu sein schienen.
Tipp zur Wahl
Für eine relativ kleine Anzahl von Elementen wären Sie wahrscheinlich daran interessiert, implizite Heaps zu verwenden, insbesondere quaternäre Heaps (implizite 4-Ary). Bei größeren Heap-Größen sollten amortisierte Strukturen wie Binomial-Heaps und Pairing-Heaps eine bessere Leistung erzielen.
quelle
Hier ist die weitere Implementierung des NGenerics-Teams:
NGenerics PriorityQueue
quelle
Ich hatte kürzlich das gleiche Problem und habe schließlich ein NuGet-Paket dafür erstellt.
Dies implementiert eine standardmäßige Heap-basierte Prioritätswarteschlange. Es hat auch alle üblichen Besonderheiten der BCL-Sammlungen:
ICollection<T>
undIReadOnlyCollection<T>
Implementierung, benutzerdefinierteIComparer<T>
Unterstützung, die Möglichkeit, eine anfängliche Kapazität anzugeben, und aDebuggerTypeProxy
der Sammlung leichte Arbeit mit in dem Debugger zu machen.Es gibt auch eine Inline Version des Pakets, die nur eine einzelne CS-Datei in Ihr Projekt installiert (nützlich, wenn Sie vermeiden möchten, dass extern sichtbare Abhängigkeiten verwendet werden).
Weitere Informationen finden Sie auf der Github-Seite .
quelle
Eine einfache Max Heap-Implementierung.
https://github.com/bharathkumarms/AlgorithmsMadeEasy/blob/master/AlgorithmsMadeEasy/MaxHeap.cs
quelle
Die folgende Implementierung einer
PriorityQueue
VerwendungSortedSet
aus der Systembibliothek.quelle
T x
und sindK key
? Ich vermute, dies ist ein Trick, um Duplikate zuzulassenT x
, und ich muss einen eindeutigen Schlüssel (z. B. UUID) generieren.