Non esiste una "implementazione di coda di priorità più efficiente" in qualsiasi lingua.
Una coda di priorità è tutta una questione di compromessi. Vedere http://en.wikipedia.org/wiki/Priority_queue
Si dovrebbe scegliere uno di questi due, in base a come si prevede di utilizzarlo:
O(log(N))
tempo di inserimento e O(1)
tempo findMin + deleteMin, o
O(1)
tempo di inserimento e O(log(N))
findMin + deleteMin time
In quest'ultimo caso, è possibile scegliere di implementare una coda di priorità con un heap di Fibonacci: http://en.wikipedia.org/wiki/Heap_(data_structure)#Comparison_of_theoretic_bounds_for_variants (come ou può vedere, heapq
che è fondamentalmente un albero binario, deve necessariamente avere O(log(N))
sia per l'inserimento e findMin + deleteMin)
Se avete a che fare con i dati con proprietà speciali (come i dati delimitate), allora si può ottenere O(1)
inserimento e O(1)
findMin + deleteMin time. Puoi farlo solo con determinati tipi di dati, perché altrimenti potresti abusare della tua coda di priorità per violare il numero O(N log(N))
legato all'ordinamento.
Per implementare qualsiasi coda in qualsiasi lingua, è sufficiente definire le operazioni insert(value)
e extractMin() -> value
.Questo generalmente richiede solo un involucro minimale dell'heap sottostante; vedi http://en.wikipedia.org/wiki/Fibonacci_heap per implementare il proprio, o utilizzare una libreria off-the-shelf di un mucchio simile come un accoppiamento Heap (una ricerca su Google ha rivelato http://svn.python.org/projects/sandbox/trunk/collections/pairing_heap.py)
Se vi interessa soltanto quale delle due si fa riferimento sono più efficiente (il codice di heapq
based da http://docs.python.org/library/heapq.html#priority-queue-implementation-notes cui è incluso sopra, contro Queue.PriorityQueue
), quindi:
ci non sembra essere qualsiasi discussione facilmente trovabili sul web come a ciò che sta effettivamente facendo Queue.PriorityQueue
; si avrebbe a fonte tuffo nel codice, che è legata alla dalla documentazione di aiuto: http://hg.python.org/cpython/file/2.7/Lib/Queue.py
224 def _put(self, item, heappush=heapq.heappush):
225 heappush(self.queue, item)
226
227 def _get(self, heappop=heapq.heappop):
228 return heappop(self.queue)
Come possiamo vedere, Queue.PriorityQueue
è anche utilizzando heapq
come un meccanismo sottostante. Pertanto sono ugualmente cattivi (asintoticamente parlando). Queue.PriorityQueue
potrebbe consentire query parallele, quindi vorrei scommettere che potrebbe avere un fattore leggermente più costante di overhead. Ma poiché sai che l'implementazione di base (e il comportamento asintotico) devono essere uguali, il modo più semplice sarebbe semplicemente di eseguirli sullo stesso set di dati di grandi dimensioni.
(Si noti che Queue.PriorityQueue
non sembra avere un modo per rimuovere le voci, mentre lo fa heapq
. Tuttavia questa è un'arma a doppio taglio: implementazioni di coda con priorità buona potrebbero eventualmente consentire di eliminare elementi in O (1) o O (log (N)), ma se usi la funzione remove_task
che hai menzionato e lasci che quelle attività zombi si accumulino nella tua coda perché non le estrai dal minimo, allora vedrai un rallentamento asintotico che non dovresti altrimenti vedere. Naturalmente, non si poteva fare questo con Queue.PriorityQueue
, in primo luogo, in modo che nessun confronto può essere fatto qui.)
Eventuali duplicati di [A coda di priorità generica per Python] (http://stackoverflow.com/questions/407734/a-generic-priority-queue -per-python) –