Code con priorità
In questa pagina 5
Una entry è una coppia (chiave, valore) con chiave in un dominio e valore in (getKey(), getValue()).
Una coda con priorità (priority queue) è una collezione di entry le cui chiavi, non necessariamente distinte, rappresentano priorità e provengono da un universo totalmente ordinato. Ingressi e uscite si alternano in modo arbitrario, le priorità in ingresso non sono ordinate, le uscite avvengono in ordine di priorità.
interfaccia PriorityQueue<K,V>:
size(), isEmpty()
insert(k, v) inserisce e restituisce la nuova entry (k, v)
min() restituisce una entry con chiave minima, senza toglierla
removeMin() restituisce e toglie una entry con chiave minimaPer convenzione chiave minima = priorità massima. Una coda basata sul massimo ha max() e removeMax() al posto di min() e removeMin().
Esempio
Partendo da una coda vuota:
| Operazione | Output | Contenuto dopo |
|---|---|---|
insert(5, A) |
||
insert(9, C) |
||
insert(3, B) |
||
insert(7, D) |
||
min() |
invariato | |
removeMin() |
||
size() |
invariato | |
isEmpty() |
falso | invariato |
L'ordine di inserimento è irrilevante per le uscite: contano solo le chiavi.
Applicazioni
Liste d'attesa (ad esempio negli aeroporti); scheduling di processi o di richieste di banda per la qualità del servizio; estrazione dei top- da una grande collezione di pattern; algoritmo di Dijkstra per i cammini minimi (vedi Cammini minimi e algoritmo di DijkstraGrafi pesati, lunghezza di un cammino e distanza; sottocammini di un cammino minimo; problema SSSP; algoritmo di Dijkstra con cloud e priority queue, rilassamento degli archi, esempio svolto; correttezza (due lemmi) e complessità O(min(n^2, (n+m) log n)) con lista non ordinata o heap; pesi non negativi.Cammini minimi e algoritmo di Dijkstra →); ordinamento (vedi sotto e Algoritmi di ordinamentoSelection sort e insertion sort (quadratici, con invarianti), merge sort (divide et impera, Theta(n log n)), quick sort (caso pessimo quadratico, medio n log n), heap sort (in loco, Theta(n log n)), ordinamento senza confronti per chiavi intere in un intervallo piccolo, limite inferiore Omega(n log n) per gli algoritmi basati su confronti.Algoritmi di ordinamento →).
Implementazione con liste
Le entry sono tenute in una lista doppiamente concatenata (vedi Liste, pile e codeRipasso degli ADT elementari: lista index-based (array) e position-based (lista doppiamente concatenata con sentinelle), pila LIFO, coda FIFO, deque, iteratori; interfacce, implementazioni e costi; array estendibile e coda circolare.Liste, pile e code →).
Lista non ordinata. insert: si aggiunge in coda, . min: si scorre tutta la lista tenendo la chiave minore, . removeMin: si trova il minimo e lo si toglie, .
Lista ordinata (per chiave crescente). min e removeMin: si guarda/toglie il primo nodo, . insert: si scorre fino alla prima chiave e si inserisce prima di essa, .
Le due liste spostano il costo da un'operazione all'altra; lo heap lo bilancia: nessuna operazione è lineare.
Ordinamento con una coda con priorità
Per ordinare chiavi: si fanno insert e poi removeMin, che restituiscono le chiavi in ordine crescente. Il costo dipende dall'implementazione:
- lista non ordinata: (è il selection sort);
- lista ordinata: (è l'insertion sort);
- heap: (è l'heap sort).
Errori comuni
- Dimenticare che le chiavi possono ripetersi:
removeMinrestituisce una entry con chiave minima. - Confondere "priorità massima" con "chiave massima": con la convenzione del corso la priorità massima è la chiave minima.
- Dire che
min()eremoveMin()hanno lo stesso costo in ogni implementazione: nello heap sono e .
Versione ripasso
- Entry = (chiave, valore). Coda con priorità: chiavi (anche ripetute) da un universo ordinato;
insert(k,v),min(),removeMin(),size(),isEmpty(); chiave minima = priorità massima. Variante sul massimo:max,removeMax. - Applicazioni: liste d'attesa, scheduling, top-, Dijkstra (vedi Cammini minimi e algoritmo di DijkstraGrafi pesati, lunghezza di un cammino e distanza; sottocammini di un cammino minimo; problema SSSP; algoritmo di Dijkstra con cloud e priority queue, rilassamento degli archi, esempio svolto; correttezza (due lemmi) e complessità O(min(n^2, (n+m) log n)) con lista non ordinata o heap; pesi non negativi.Cammini minimi e algoritmo di Dijkstra →), ordinamento.
- Con lista (vedi Liste, pile e codeRipasso degli ADT elementari: lista index-based (array) e position-based (lista doppiamente concatenata con sentinelle), pila LIFO, coda FIFO, deque, iteratori; interfacce, implementazioni e costi; array estendibile e coda circolare.Liste, pile e code →): non ordinata
insert,min/removeMin; ordinatamin/removeMin,insert. Heap: , , (vedi HeapAlbero binario completo e sua altezza floor(log2 n); heap = albero completo con heap-order property; proprietà (radice minima, cammini non decrescenti); rappresentazione su array con level numbering; insert con up-heap bubbling, removeMin con down-heap bubbling, rimozione di una entry qualsiasi; invarianti e costi Theta(log n); esempio svolto.Heap →). - Ordinamento con coda con priorità (
insert+removeMin): lista non ordinata = selection sort ; lista ordinata = insertion sort ; heap = heap sort (vedi Algoritmi di ordinamentoSelection sort e insertion sort (quadratici, con invarianti), merge sort (divide et impera, Theta(n log n)), quick sort (caso pessimo quadratico, medio n log n), heap sort (in loco, Theta(n log n)), ordinamento senza confronti per chiavi intere in un intervallo piccolo, limite inferiore Omega(n log n) per gli algoritmi basati su confronti.Algoritmi di ordinamento →). - Errori: assumere chiavi distinte; priorità massima = chiave massima; stesso costo per
mineremoveMin.