Code Codecon conpriorità priorità ✦ Coda con priorità Una struttura dati che serve a memorizzare/organizzare un insieme S di elementi x ✦ Informatica II Ciascun elemento x ha associato un valore di priorità. Solitamente la priorità è un numero intero (positivo) ✦ Capitolo 11 (in parte, e parte del 10) Progettazione di algoritmi ✦ Gli elementi di S sono organizzati rispetto al valore delle priorità Solitamente l’elemento “più importante”, con la priorità “migliore”, è quello con la priorità: ✦ maggiore (priorità decrescente), oppure ✦ minore (priorità crescente) ✦ ✦ L’operazione principale è: estrarre l’elemento “più importante” Vi sono molti modi di implementare le code con priorità. Vedremo il più semplice: utilizzare le liste (ordinate o non ordinate) ✦ Adattamento delle slide originali di A.Montresor. Disponibili secondo Creative Commons Attribution-NonCommercial-ShareAlike License. 2 Specifica generale delle code con priorità Code Codecon conpriorità: priorità:usando usandoleleliste liste Gli elementi della coda con priorità sono semplicemente organizzati in una lista di struct/record ✦ ✦ Se si implementa la lista con i puntatori, i record devono avere (almeno) i campi: ITEM elemento; integer priorità; Più il/i puntatore/i necessario/i a connettere gli elementi della lista Due scelte possibili: ✦ ✦ Lista non ordinata ✦ Lista ordinata rispetto al valori dei campi priorità Domanda: Nei due casi, come cambiano le complessità delle operazioni min(), deleteMin(), insert(), decrease() ? Esercizio: Scrivere lo pseudo-codice delle operazioni usando le operazioni delle liste non ordinate. Poi modificarle in modo da imporre/mantenere l’ordinamento rispetto al valore del campo priorità ✦ 3 4 Progettazione di algoritmi (cap.11) Classificazione di un problema Dato un problema qualsiasi come lo risolviamo? Le principali classi di problemi: ✦ Non ci sono “ricette generali” per progettare un algoritmo che lo risolva in modo efficiente ✦ ✦ Problemi decisionali: Il dato di ingresso soddisfa una certa proprietà? ✦ Soluzione: risposta sì/no ✦ E’ possibile evidenziare quattro aspetti generali ✦ Esempio: Stabilire se un grafo è connesso ✦ Classificazione del problema (che tipo di problema voglio risolvere) ✦ Caratterizzazione della soluzione (che caratteristiche ha la soluzione cercata) ✦ ✦ Tecnica di progetto (scelta di una tecnica particolare) ✦ Problemi di ricerca: Spazio di ricerca: insieme delle “soluzioni” possibili ✦ Utilizzo di strutture dati (quali si adattano meglio al “struttura” del problema, e della soluzione?) ✦ Soluzione ammissibile: soluzione che rispetta certi vincoli ✦ Esempio: cercare la posizione di una sottostringa in una stringa; ✦ 5 Classificazione di un problema 6 Caratterizzazione della soluzione Problemi di ottimizzazione: Occorre definire la soluzione in modo formale ✦ ✦ Ogni soluzione è associata ad una funzione di costo ✦ Vogliamo trovare la soluzione di costo minimo ✦ Esempio: cammino più breve fra due nodi in un grafo ✦ Spesso la formulazione è banale... ✦ ... ma può suggerire una prima idea di algoritmo risolutivo ✦ Esempio: Selection Sort: ✦ Data una sequenza di n elementi, una permutazione ordinata è formata dall’elemento minimo seguita da una permutazione ordinata dei restanti n-1 elementi Problemi di approssimazione: ✦ A volte, trovare la soluzione ottima è computazionalmente troppo oneroso ✦ Le caratteristiche matematiche della soluzione possono suggerire una possibile tecnica per risolvere il problema ✦ Ci si accontenta allora di una soluzione approssimata ma calcolabile velocemente: ✦ Esempio: sottostruttura ottima → programmazione dinamica (vedremo…) ✦ costo basso, ma non sappiamo se ottimo (problema supplementare: determinare, se possibile, una stima di quanto è “distante” l’ottimo) ✦ Esempio: problema del commesso viaggiatore ✦ 7 8 Il problema dei cammini minimi in un grafo pesato Variazioni sul tema: Input: un grafo diretto pesato Cammini minimi da sorgente unica ✦Input: nodo sorgente r ✦Output: i cammini minimi che vanno da r a tutti gli altri nodi v ✦ ✦ Grafo orientato G=(V,E) ✦ Un nodo di partenza r ✦ Cammino minimo tra una coppia di vertici ✦Input: una coppia di vertici r, d ✦Output: un cammino minimo che parta da r e arrivi in d ✦Idea: Si risolve il primo problema e si estrae il cammino richiesto. Non si conoscono algoritmi che abbiano tempo di esecuzione migliore di questo. ✦ Funzione di peso w: E → R ✦ Definizione ✦ Dato un cammino c = v1,v2, ..., vk con k > 1, il costo del cammino è dato da ✦ Cammini minimi tra tutte le coppie di vertici ✦Input: il grafo. ✦Output: i cammini minimi fra tutte le coppie di vertici. ✦Tecnica usata: Programmazione dinamica (vedremo…) ✦ Output ✦ Per ogni nodo u ∈ V, trovare un cammino da r ad u il cui costo sia minimo (shortest path), ovvero più piccolo o uguale del costo di qualunque altro cammino da r a u. ✦ 9 Problema dei cammini minimi 1 0 Esempi di input possibili Come descrivere la soluzione (cioè, l’output dell’algoritmo): ✦ Nella figura ✦ Si noti che due cammini minimi possono avere un tratto comune: ✦ ✦ un grafo G1 con un ciclo negativo ✦ un grafo G2 senza cicli negativi ✦ una soluzione ammissibile per G2 ✦ una soluzione ottima per G2 Non possono convergere in un nodo comune s dopo aver percorso un tratto iniziale distinto. Cioè non è possibile che: ✦ Domanda: Perche? Quindi, una soluzione ammissibile altro non è che un albero di copertura, radicato in r, che include un cammino da r ad ogni altro nodo. ✦ 1 1 1 2 Caratterizzazione matematica della soluzione ✦ Programma prototipo (istanziabile cambiando la struttura dati) Definizione Sia T una soluzione ammissibile. Ogni nodo u è caratterizzato da un valore du, che indica la distanza di u da r in T, uguale al costo del cammino fra r ed u in T ✦ ✦ Quali caratteristiche devono avere le distanze affinché T sia una ottima? ✦ Teorema di Bellman ✦ Una soluzione ammissibile T è ottima se e solo se valgono le seguenti condizioni: dv = du + w(u,v) per ogni arco (u,v) ∈ T dv ≤ du + w(u,v) per ogni arco (u,v) ∈ E ✦ (continua nel prossimo lucido…) Esercizio: Dimostrare il Teorema di Bellman 13 Programma prototipo (istanziabile cambiando la struttura dati) 14 Algoritmo di Dijkstra (1959) Struttura dati: ✦ Coda con priorità, realizzata tramite vettore/lista non ordinati 15 16 Algoritmo di Dijkstra (1959) Algoritmo di Dijkstra Ipotesi: tutti i pesi sono positivi ✦ Ogni nodo viene estratto una e una sola volta ✦ Al momento dell’estrazione la sua distanza è minima ✦ Costo totale: O(n2) ✦ Costo Ripetizioni Riga (1): O(n) 1 Riga (2): O(n) O(n) Riga (3): O(1) O(n) Riga (4): O(1) O(m) ✦ ✦ ✦ ✦ 17 18 Algoritmo di Bellman - Ford - Moore (1958) Algoritmo di Bellman - Ford - Moore (1958) Funziona anche con pesi negativi ✦ Struttura dati: ✦ Coda In pratica esegue una BFS in cui ogni nodo viene “marcato” diminuendo il peso del cammino. Si può visitare più volte un nodo, ma al più n-1 volte, e ogni volta diminuisco il peso del cammino. Quindi ogni nodo viene estratto al massimo n-1 volte ✦ ✦ Si compiono piu “passate”. La nozione di passata k-esima è definita ricorsivamente: ✦per k = 0, la zero-esima passata consiste nell’estrazione del nodo r dalla coda S; ✦per k > 0, la k-esima passata consiste nell’estrazione di tutti i nodi presenti in S al termine della passata (k − 1)-esima. ✦ La passata k corrisponde ai cammini di lunghezza k ✦ Costo totale: O(mn) , infatti: Costo ✦Riga (1): O(1) ✦Riga (2): O(1) ✦Riga (3): O(1) ✦ 19 Ripetizioni 1 O(n2) O(mn) 20