Szukam implementacji .NET struktury danych kolejki priorytetowej lub sterty
Kolejki priorytetowe to struktury danych, które zapewniają większą elastyczność niż proste sortowanie, ponieważ umożliwiają wprowadzanie nowych elementów do systemu w dowolnych odstępach czasu. Znacznie bardziej opłacalne jest wstawianie nowego zadania do kolejki priorytetowej niż ponowne sortowanie wszystkiego przy każdym takim przybyciu.
Podstawowa kolejka priorytetowa obsługuje trzy podstawowe operacje:
- Wstaw (Q, x). Biorąc pod uwagę element x z kluczem k, wstaw go do kolejki priorytetowej Q.
- Znajdź minimum (Q). Zwraca wskaźnik do elementu, którego wartość klucza jest mniejsza niż jakikolwiek inny klucz w kolejce priorytetowej Q.
- Usuń minimum (Q). Usuń element z kolejki priorytetowej Q, której klucz jest minimalny
Jeśli nie szukam w niewłaściwym miejscu, nie ma takiego w ramach. Czy ktoś zdaje sobie sprawę z dobrego, czy powinienem wyrzucić własny?
c#
.net
data-structures
heap
priority-queue
Doug McClean
źródło
źródło
Odpowiedzi:
Lubię używać klas
OrderedBag
iOrderedSet
w PowerCollections jako kolejek priorytetowych.źródło
Może Ci się spodobać IntervalHeap z biblioteki kolekcji ogólnej C5 . Cytując instrukcję obsługi
Interfejs API jest dość prosty
Zainstaluj z Nuget https://www.nuget.org/packages/C5 lub GitHub https://github.com/sestoft/C5/
źródło
Oto moja próba sterty .NET
Niektóre testy:
źródło
IEqualityComparer<T>
nie wystarczyłoby, ponieważ powiedziałoby to tylko, czy dwa przedmioty są równe, a ty musisz znać relację między nimi (kto jest mniejszy / większy). To prawda, że mogłem skorzystaćIComparer<T>
...oto jeden, który właśnie napisałem, może nie jest tak zoptymalizowany (używa posortowanego słownika), ale jest prosty do zrozumienia. możesz wstawiać obiekty różnego rodzaju, więc nie ma ogólnych kolejek.
źródło
Znalazłem jeden autorstwa Juliana Bucknalla na jego blogu tutaj - http://www.boyet.com/Articles/PriorityQueueCSharp3.html
Zmodyfikowaliśmy go nieznacznie, aby elementy o niskim priorytecie w kolejce z czasem „wyskoczyły” na szczyt, aby nie doznały głodu.
źródło
Jak wspomniano w zbiorach Microsoft dla platformy .NET , Microsoft napisał (i udostępnił online) 2 wewnętrzne klasy PriorityQueue w .NET Framework. Ich kod jest dostępny do wypróbowania.
EDYCJA: Jak skomentował @ mathusum-mut, w jednej z wewnętrznych klas PriorityQueue Microsoftu jest błąd (społeczność SO oczywiście go naprawiła): Błąd w wewnętrznej PriorityQueue <T> Microsoftu?
źródło
PriorityQueue<T>
we wspólnym źródle Microsoft są oznaczoneinternal
specyfikatorem dostępu. Są więc używane tylko przez wewnętrzne funkcjonalności frameworka. Nie są one dostępne do powszechnego użytku po prostu przez odwołaniewindowsbase.dll
w projekcie C #. Jedynym sposobem jest skopiowanie udostępnionego źródła do samego projektu w pliku klasy.Przydatna może być ta implementacja: http://www.codeproject.com/Articles/126751/Priority-queue-in-Csharp-with-help-of-heap-data-st.aspx
jest ogólny i oparty na strukturze danych sterty
źródło
łatwo.
źródło
for (var n2 = n / 2; n > 0 && comparer.Compare(v, heap[n2]) > 0; n = n2, n2 /= 2) heap[n] = heap[n2];
i zastanawiam się, czy warto było mieć jedną podszewkęUżyj translatora Java do C # na implementacji Java (java.util.PriorityQueue) w ramach kolekcji Java lub bardziej inteligentnie użyj algorytmu i kodu rdzenia i podłącz go do własnej klasy C #, co jest zgodne z ramą kolekcji C # Interfejs API dla kolejek lub przynajmniej kolekcji.
źródło
AlgoKit
Napisałem bibliotekę open source o nazwie AlgoKit , dostępną za pośrednictwem NuGet . Zawiera:
Kod został gruntownie przetestowany. Zdecydowanie polecam spróbować.
Przykład
Dlaczego te trzy hałdy?
Optymalny wybór implementacji jest silnie zależny od nakładów - jak pokazują Larkin, Sen i Tarjan w A-back-to-podstawy studium empirycznym kolejek priorytetowych , arXiv: 1403.0252v1 [cs.DS] . Testowali niejawne stosy d-ary, stosy parowania, stosy Fibonacciego, stosy dwumianowe, jawne stosy d-ary, stosy parowania rang, stosy trzęsień, stosy naruszenia, stosy osłabione rangą osłabione i surowe stosy Fibonacciego.
AlgoKit zawiera trzy rodzaje hałd, które wydają się najbardziej wydajne wśród testowanych.
Wskazówka dotycząca wyboru
W przypadku stosunkowo niewielkiej liczby elementów prawdopodobnie zainteresowałbyś się stosami niejawnymi, zwłaszcza stertami czwartorzędowymi (niejawne 4-ary). W przypadku operacji na większych rozmiarach, amortyzowane struktury, takie jak stosy dwumianowe i stosy parowania, powinny działać lepiej.
źródło
Oto kolejna implementacja zespołu NGenerics:
NGenerics PriorityQueue
źródło
Ostatnio miałem ten sam problem i ostatecznie stworzyłem do tego pakiet NuGet .
To implementuje standardową kolejkę priorytetową opartą na stercie. Ma również wszystkie typowe cechy kolekcji BCL:
ICollection<T>
iIReadOnlyCollection<T>
implementację, niestandardoweIComparer<T>
wsparcie, możliwość określenia początkowej pojemności orazDebuggerTypeProxy
ułatwienie pracy z kolekcją w debuggerze.Istnieje również wersja Inline pakietu, która po prostu instaluje jeden plik .cs w twoim projekcie (przydatne, jeśli chcesz uniknąć przyjmowania zewnętrznych widocznych zależności).
Więcej informacji jest dostępnych na stronie github .
źródło
Prosta implementacja Max Heap.
https://github.com/bharathkumarms/AlgorithmsMadeEasy/blob/master/AlgorithmsMadeEasy/MaxHeap.cs
źródło
Następująca implementacja
PriorityQueue
zastosowańSortedSet
z biblioteki System.źródło
T x
iK key
? Zgaduję, że jest to sztuczka pozwalająca na duplikowanieT x
i muszę wygenerować unikalny klucz (np. UUID)?