So che è possibile realizzare funzionalità di tasto decremento in O (log n) ma non so come?Come posso implementare la funzionalità di chiave decrescente nell'heapq di Python?
risposta
Per implementare efficacemente "tasto di riduzione", è necessario accedere alla funzionalità "decrementa questo elemento E scambia questo elemento con un figlio finché non viene ripristinata la condizione dell'heap". In heapq.py, si chiama _siftdown
(e allo stesso modo _siftup
per INcrementing). Quindi la buona notizia è che le funzioni ci sono ... la cattiva notizia è che i loro nomi iniziano con un trattino basso, che indica che sono considerati "dettagli di implementazione interna" e non dovrebbero essere accessibili direttamente dal codice dell'applicazione (la prossima versione del la libreria standard potrebbe cambiare le cose e rompere il codice usando tali "interni").
Sta a voi decidere se si vuole ignorare l'avviso leading- _
, utilizzare O (N) heapify
invece di O (log N) vagliatura, o reimplementare alcune o tutte le funzionalità di heapq per rendere le primitive vagliatura " esposti come parti pubbliche dell'interfaccia ". Poiché la struttura dei dati di heapq è documentata e pubblica (solo una lista), penso che la scelta migliore sia probabilmente una reimplementazione parziale: copiare le funzioni di setacciamento da heapq.py nel codice dell'applicazione, in sostanza.
Immaginate di utilizzare un heap come coda di priorità, in cui vi sono un sacco di attività rappresentate da stringhe e ogni attività ha una chiave. Per concretezza, guarda: task_list = [[7,"do laundry"], [3, "clean room"], [6, "call parents"]]
dove ogni attività in task_list
è una lista con una priorità e una descrizione. Se si esegue heapq.heapify(task_list)
, si ottiene l'array per mantenere invariato l'heap. Tuttavia, se si desidera modificare la priorità di "do laundry" su 1, non si ha modo di sapere dove "do laundry" si trova nell'heap senza una scansione lineare attraverso l'heap (quindi non può fare diminuire_key in tempo logaritmico) . Nota: decrease_key(heap, i, new_key)
richiede di conoscere l'indice del valore da modificare nell'heap.
Anche se si mantiene un riferimento a ciascun sottolista e si modifica effettivamente la chiave, non è ancora possibile farlo nel tempo di registrazione. Dal momento che una lista è solo un riferimento a un gruppo di oggetti mutabili, puoi provare a fare qualcosa come ricordare l'ordine originale dell'attività: (in questo caso "fare il bucato" era la 0a attività nel tuo originale task_list
):
task_list = [[7, "do laundry"], [3, "clean room"], [6, "call parents"]]
task_list_heap = task_list[:] # make a non-deep copy
heapq.heapify(task_list_heap)
# at this point:
# task_list = [[7, 'do laundry'], [3, 'clean room'], [6, 'call parents']]
# task_list_heap = [3, 'clean room'], [7, 'do laundry'], [6, 'call parents']]
# Change key of first item of task_list (which was "do laundry") from 7 to 1.
task_list[0][0] = 1
# Now:
# task_list = [[1, 'do laundry'], [3, 'clean room'], [6, 'call parents']]
# task_list_heap = [3, 'clean room'], [1, 'do laundry'], [6, 'call parents']]
# task_list_heap violates heap invariant at the moment
Tuttavia, è ora necessario chiamare heapq._siftdown(task_list_heap, 1)
per mantenere l'invariante heap in tempo di log (heapq.heapify
è tempo lineare), ma purtroppo non si conosce l'indice di "fare il bucato" in task_list_heap
(il heap_index
in questo caso è 1).
Quindi dobbiamo implementare il nostro heap per tenere traccia dello heap_index
di ciascun oggetto; ad esempio, avere un list
(per l'heap) e un dict
mappare ogni oggetto al suo indice nell'heap/list (che viene aggiornato quando le posizioni heap vengono scambiate aggiungendo un fattore costante a ogni scambio). Puoi leggere heapq.py e implementare te stesso come la procedura è semplice; tuttavia, altri hanno già implementato questo tipo di HeapDict.
Il heapq documentation ha una voce su esattamente come fare questo.
Tuttavia, ho scritto un pacchetto heap
che fa esattamente questo (è un wrapper intorno a heapq
).Quindi, se avete pip
o easy_install
si potrebbe fare qualcosa di simile
pip install heap
Poi, nel tuo codice di scrittura
from heap.heap import heap
h = heap()
h['hello'] = 4 # Insert item with priority 4.
h['hello'] = 2 # Update priority/decrease-key has same syntax as insert.
E è abbastanza nuovo, però, quindi potrebbe essere pieno di bug.
La chiave di riduzione è un'operazione indispensabile per molti algoritmi (Algoritmo di Dijkstra, A *, OPTICS), mi chiedo perché la coda di priorità incorporata di Python non la supporti.
Sfortunatamente, non ero in grado di scaricare il pacchetto di math4tots.
Ma, sono stato in grado di trovare l'implementazione this di Daniel Stutzbach. Ha funzionato perfettamente per me con Python 3.5.
- 1. Funzione comparatore di Backbone.js, come posso implementare l'ordine decrescente?
- 2. Come implementare la funzionalità di annullamento?
- 3. Come implementare funzionalità come la funzione "Nuova storia" di Facebook?
- 4. Come posso implementare funzionalità di Single Sign-On con Check_MK?
- 5. Come implementare la funzionalità di Excel Solver in C#?
- 6. È possibile implementare la funzionalità di rendimento di Python nella C libera?
- 7. come implementare la funzionalità di annullamento in opengl in Android
- 8. Come implementare la funzionalità di ricerca in C#/ASP.NET MVC
- 9. Come implementare la funzionalità di annullamento/ripristino in Eclipse FormEditor?
- 10. Come implementare la funzionalità di ordinamento in gridview?
- 11. Come posso implementare la nuova funzionalità di scorciatoie da tastiera di iPad Pro?
- 12. Chiave primaria crescente vs decrescente
- 13. Implementare la funzionalità di paging (skip/take) con questa query
- 14. Come posso implementare la funzionalità di awt.CardLayout nella mia applicazione javaFX 2.0?
- 15. Elenco Python in ordine decrescente
- 16. Come posso implementare la funzione di cancellazione in SVG?
- 17. Posso sospendere la funzionalità di iScroll?
- 18. Come posso implementare un generatore in C++?
- 19. Come posso bloccare con la chiave di cache?
- 20. Come posso replicare la funzionalità di un wget con node.js?
- 21. Posso usare le funzionalità di C++ estendendo Python?
- 22. Riprendi la funzionalità di download in NSURLConnection
- 23. come implementare la funzione `zip` di python in golang?
- 24. Python: come implementare __getattr __()?
- 25. dizionario python ordinamento in ordine decrescente in base ai valori
- 26. NSArray. Come posso implementare la funzione Mappa?
- 27. Come si può ottenere la funzionalità Python di isidentifer() in Python 2.6?
- 28. Si tratta di un modo ragionevole per implementare la funzionalità "ricordami"
- 29. Come implementare la corrispondenza delle stringhe Unicode piegando in python
- 30. È possibile implementare la funzionalità SystemTrayIcon nell'applicazione Qt Quick
Il collegamento a heapq.py sembra essere scaduto. Per comodità ecco un altro link all'implementazione python: http://hg.python.org/cpython/file/2.7/Lib/heapq.py – Jordan
vuoi dire "scambiare questo elemento con il suo _parent_ fino a quando non viene ripristinata la condizione dell'heap"? (supponevo che ci fossero elementi, '[2, 3, 5]', quindi '2' sarebbe il genitore, e' 3' e '5' sarebbero i suoi due figli) – tscizzle