Estou procurando uma implementação .NET de uma fila de prioridade ou estrutura de dados de heap
As filas prioritárias são estruturas de dados que fornecem mais flexibilidade do que a classificação simples, porque permitem que novos elementos entrem no sistema em intervalos arbitrários. É muito mais econômico inserir um novo trabalho em uma fila prioritária do que reorganizar tudo em cada chegada.
A fila de prioridade básica suporta três operações principais:
- Inserir (Q, x). Dado um item x com a chave k, insira-o na fila de prioridade Q.
- Encontre-Mínimo (Q). Retorne um ponteiro para o item cujo valor da chave é menor que qualquer outra chave na fila de prioridade Q.
- Excluir-mínimo (Q). Remova o item da fila de prioridade Q cuja chave é mínima
A menos que eu esteja procurando no lugar errado, não há um na estrutura. Alguém está ciente de uma boa ou devo fazer o meu próprio?
c#
.net
data-structures
heap
priority-queue
Doug McClean
fonte
fonte
Respostas:
Eu gosto de usar as classes
OrderedBag
eOrderedSet
no PowerCollections como filas prioritárias.fonte
Você pode gostar do IntervalHeap da C5 Generic Collection Library . Para citar o guia do usuário
A API é bastante simples
Instale a partir do Nuget https://www.nuget.org/packages/C5 ou GitHub https://github.com/sestoft/C5/
fonte
Aqui está minha tentativa de um heap .NET
Alguns testes:
fonte
IEqualityComparer<T>
não seria suficiente, pois isso apenas informa se dois itens são iguais, enquanto você precisa conhecer a relação entre eles (quem é menor / maior). É verdade que eu poderia ter usadoIComparer<T>
...Aqui está um que acabei de escrever, talvez não seja tão otimizado (apenas usa um dicionário classificado), mas simples de entender. você pode inserir objetos de tipos diferentes, para que não haja filas genéricas.
fonte
Encontrei um de Julian Bucknall em seu blog aqui - http://www.boyet.com/Articles/PriorityQueueCSharp3.html
Modificamos um pouco para que os itens de baixa prioridade na fila acabassem subindo para o topo com o tempo, para que não sofressem fome.
fonte
Conforme mencionado nas Coleções Microsoft para .NET , a Microsoft escreveu (e compartilhou online) 2 classes internas PriorityQueue no .NET Framework. O código deles está disponível para teste.
EDIT: Como comentou @ mathusum-mut, há um bug em uma das classes PriorityQueue internas da Microsoft (a comunidade SO, é claro, forneceu correções para isso): Bug no PriorityQueue interno da Microsoft <T>?
fonte
PriorityQueue<T>
na fonte compartilhada da Microsoft estão marcadas cominternal
especificador de acesso. Portanto, eles são usados apenas pelas funcionalidades internas da estrutura. Eles não estão disponíveis para consumo geral apenas consultandowindowsbase.dll
um projeto C #. A única maneira é copiar a fonte compartilhada no próprio projeto dentro de um arquivo de classe.Você pode achar útil esta implementação: http://www.codeproject.com/Articles/126751/Priority-queue-in-Csharp-with-help-of-heap-data-st.aspx
é genérico e baseado na estrutura de dados da pilha
fonte
fácil.
fonte
for (var n2 = n / 2; n > 0 && comparer.Compare(v, heap[n2]) > 0; n = n2, n2 /= 2) heap[n] = heap[n2];
e se perguntam se valeu de um revestimentoUse um tradutor de Java para C # na implementação Java (java.util.PriorityQueue) na estrutura Java Collections, ou use de forma mais inteligente o algoritmo e o código principal e conecte-o a uma classe C # de sua preferência, que adere à estrutura C # Collections API para filas ou pelo menos coleções.
fonte
AlgoKit
Eu escrevi uma biblioteca de código aberto chamada AlgoKit , disponível via NuGet . Contém:
O código foi extensivamente testado. Definitivamente, recomendo que você experimente.
Exemplo
Por que esses três montões?
A escolha ideal da implementação é fortemente dependente de entrada - como mostram Larkin, Sen e Tarjan em Um estudo empírico de base sobre filas de prioridade , arXiv: 1403.0252v1 [cs.DS] . Eles testaram pilhas d-árias implícitas, pilhas de emparelhamento, pilhas de Fibonacci, pilhas binomiais, pilhas d-árias explícitas, pilhas de emparelhamentos de classificação, pilhas de terremotos, pilhas de violação, pilhas fracas com descontração e pilhas estritas de Fibonacci.
O AlgoKit apresenta três tipos de pilhas que parecem ser mais eficientes entre as testadas.
Dica sobre a escolha
Para um número relativamente pequeno de elementos, você provavelmente estaria interessado em usar pilhas implícitas, especialmente pilhas quaternárias (4-ário implícito). No caso de operar em tamanhos de heap maiores, as estruturas amortizadas, como pilhas binomiais e pilhas de emparelhamento, devem ter um desempenho melhor.
fonte
Aqui está outra implementação da equipe NGenerics:
NGenerics PriorityQueue
fonte
Eu tive o mesmo problema recentemente e acabei criando um pacote NuGet para isso.
Isso implementa uma fila de prioridade padrão baseada em heap. Ele também tem todas as sutilezas habituais das coleções BCL:
ICollection<T>
eIReadOnlyCollection<T>
implementação, costumeIComparer<T>
apoio, capacidade de especificar uma capacidade inicial e umDebuggerTypeProxy
para fazer a coleta de mais fácil trabalhar com no depurador.Há também uma versão Inline do pacote que apenas instala um único arquivo .cs no seu projeto (útil se você deseja evitar a dependência externa visível).
Mais informações estão disponíveis na página do github .
fonte
Uma implementação simples de Max Heap.
https://github.com/bharathkumarms/AlgorithmsMadeEasy/blob/master/AlgorithmsMadeEasy/MaxHeap.cs
fonte
A seguinte implementação de um
PriorityQueue
usosSortedSet
da biblioteca do sistema.fonte
T x
eK key
? Eu estou supondo que este é um truque para permitir duplicarT x
, e eu preciso gerar uma chave única (por exemplo, UUID)?