TDA Priority Queue. Situazioni concrete. Definizione. Alta priorità come trovarla? Relazione di ordine totale ( ) Le implementazioni che vedremo

Documenti analoghi
Esercizio. Strutture Dati

Code a priorità (comparatore) Set Mappe. TDA Priority Queue: def. informale

Code a priorità. Progettazione di Algoritmi Matricole congrue a 1. Docente: Annalisa De Bonis

L ADT Priority Queues Implementazione di PQ mediante Sequenza Alberi Heap Heap Sort Adaptable Priority Queues

Il TDA Dictionary. Definizione informale. I metodi del TDA Dictionary 1. Applicazioni. I metodi del TDA Dictionary 2. I metodi del TDA Dictionary 3

Definizione informale

Definizione informale. Il TDA Dictionary (dizionario) modella una collezione di voci su cui è possibile effettuare delle ricerche

Il TDA Map. Tabelle hash

Definizione informale. Il TDA Map memorizza coppie formate da una chiave k e da un valore v. La coppia è chiamata entry. Ogni chiave deve essere unica

Il TDA Map. Definizione informale. I metodi del TDA Map 2. I metodi del TDA Map 1. Interfaccia Map 1 NO_SUCH_KEY. Tabelle hash

ADT albero binario completo

ADT Dizionario. Come nella Mappa: Diversamente dalla Mappa:

Il TDA List è la versione orientata agli oggetti della struttura dati lista. Una sequenza di nodi

List. Il TDA List. Interfaccia Position. Il TDA Position. Il TDA List 1. Ancora su Position

ADT Mappa. Le chiavi (il mezzo per accedere agli elementi) hanno lo scopo di rendere efficiente la ricerca. Strutture Dati

Heap e Code di Priorità

Implementazione con alberi binari di ricerca

STRUTTURE DATI: OLTRE GLI ARRAY LISTE

LINKEDLIST: implementazione iteratore. LINKEDLIST: iteratore INNERITERATOR INNERITERATOR

Fondamenti di Informatica e Laboratorio T-AB T-15 Strutture dati

Metodi di una Collection

Lezione 15 programmazione in Java. Nicola Drago Dipartimento di Informatica Università di Verona

Liste concatenate. Violetta Lonati

Corso: Strutture Dati Docente: Annalisa De Bonis

Algoritmi di ordinamento

heap heap heap? max- e min-heap concetti ed applicazioni heap = catasta condizione di heap non è una struttura ordinata

Alberi. Strutture dati: Alberi. Alberi: Alcuni concetti. Alberi: definizione ricorsiva. Alberi: Una prima realizzazione. Alberi: prima Realizzazione

Esempi in Java di program.ne O-O

Algoritmi di ordinamento

Parte di laboratorio

Liste concatenate. Collezione ordinata di nodi. Carlo Paolo Simona. Anna. ciascun nodo contiene due riferimenti:

Alberi Binari Alberi Binari

Strutture dati. Il che cosa e il come. F. Damiani - Alg. & Lab. 04/05

Fondamenti di Informatica T-1

Corso sul linguaggio Java

Binary Search Trees ( 10.1)

Esercizio. Scrivere una classe ListMap<K, V> che implementa la mappa con una lista. Strutture Dati

Esercizi proposti per il corso di Strutture Dati

Fondamenti di Informatica. Algoritmi di Ricerca e di Ordinamento

Esercizi riassuntivi (Fondamenti di Informatica 2 Walter Didimo) Soluzioni

Conoscere l uso delle collezioni in Java. Conoscere il concetto di Generics (programmazione

Algoritmi di Ricerca. Esempi di programmi Java

Implementazione della coda con liste concatenate. x v. il front della coda è memorizzato nel primo nodo (head) della lista

tipi di dato astratti

La struttura dati CODA

Algoritmi e Strutture Dati

Dati e Algoritmi 1: A. Pietracaprina. Priority Queue (I Parte)

Implementazione Java di un ADT

Algoritmi e Strutture Dati

Algoritmi e Strutture Dati

Richiami Java e Arrays

SOMMARIO STACK. STACK: specifica STACK

La Standard Template Library Heap, algoritmi e funtori

Implementazione dell albero binario in linguaggio C++

Alberi ( GT. 7 ) In informatica, un albero è un modello astratto con cui viene rappresentata una struttura gerarchica

come segue: data una collezione C di elementi e una un elemento che verifica la proprietà P

Esercitazione 5 Alberi Binari di Ricerca

E` un tipo astratto di dati che supporta tutti i metodi dell'adt Array list e dell'adt Lista di nodi più i seguenti:

ADT LISTA: altre operazioni non primitive ADT LISTA COSTRUZIONE ADT LISTA COSTRUZIONE ADT LISTA (2)

Fondamenti di Informatica T1 Interfaccia Comparable Collezioni

Problemi di ordinamento

Un heap binario è un albero binario con le seguenti caratteristiche:

Le liste. Prof. Francesco Accarino IIS Sesto San Giovanni Via Leopardi 132

semplici ogni elemento contiene un riferimento al successivo doppie ogni elemento contiene un riferimento al successivo e al precedente

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica

Esercizi Capitolo 10 - Code con priorità e insiemi disgiunti

Lezione 8 Struct e qsort

Esercizio laboratorio (Java 0) Raccolto stampato nel turno successivo di laboratorio

Spesso sono definite anche le seguenti operazioni:

Alberi. In informatica, un albero è un modello astratto di una struttura dati gerarchica

Alberi binari di ricerca

lezione 9 min-heap binario Heap e Alberi posizionali generali

Dati e Algoritmi 1: A. Pietracaprina. Priority Queue (II parte)

TDA Position (TDA List Sequence)

Programmazione a Oggetti Modulo B

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 2

Le liste. Le liste linkate

Array. Walter Didimo

Algoritmi e Strutture Dati & Laboratorio di Algoritmi e Programmazione

Albero Binario GT 7.3. interfacce di Positio<E>, Tree<E>, e BinaryTree<E>; il file TestLinkedBinaryTree.java

Alberi Binario in Java

Orario delle lezioni LABORATORIO TEORIA. mercoledì. martedì aula P/4. lab Turing. Strutture Dati

Algoritmi di Ricerca. Esempi di programmi Java. Prof. Angela Bonifati

Heap e code di priorità

Algoritmi di Ricerca. Esempi di programmi Java

Prova di Algoritmi e s.d. (1o anno) 17 Settembre TESTO e RISPOSTE

Argomenti della lezione. Introduzione agli Algoritmi e alle Strutture Dati. Lista Lineare. Lista Lineare come Tipo di Dato Astratto

Fondamenti di Informatica

Il tipo astratto di dati Node List

Lezione 6 Struct e qsort

Esercizi Capitolo 10 - Code con priorità e insiemi disgiunti

Dato un insieme S di n elementi totalmente ordinato, l'algoritmo di ordinamento detto HeapSort ha le seguenti caratteristiche:

heap concetti ed applicazioni

Implementazione ADT: Alberi

Coda a doppio ingresso (Deque)

Transcript:

TDA Priority Queue TDA Coda a priorità [GT3, cap.7,7.1-7.2] Situazioni concrete La vita è piena di decisioni ognuno ha le sue priorità Ad es., decidere se questo fine settimana studiare, dormire, uscire Come si fa? E poi studiare cosa? Ognuno sa cosa è importante (in assoluto o in relativo ) Esempio: centro di controllo aereo. Si stabiliscono delle priorità tra i voli per decidere quale deve atterrare prima (quello più vicino!). Talvolta la priorità può cambiare (ad esempio, un aereo ha poco carburante, DEVE atterrare per primo) Algoritmi su grafi per cammini minimi o per il MST: i vertici hanno abbinate delle priorità, in base alle quali li considero nell algoritmo. Studiamo una struttura dati per gestire elementi a cui è assegnata una priorità 2 Definizione Una coda a priorità (PQ) è un contenitore di elementi, ciascuno dei quali possiede una chiave (tipicamente numerica) Le implementazioni che vedremo Due implementazioni usando liste (facili anche se non molto efficienti) La chiave viene assegnata nel momento in cui l elemento è inserito nella coda (può essere modificata successivamente) Le chiavi determinano la priorità degli elementi, ovvero l ordine in cui vengono rimossi dalla coda (inserimenti arbitrari): rimuovo l elemento che ha la priorità maggiore. In realtà non c è una nozione di posizione, ma memorizzo gli elementi in base alle priorità. 3 C è una implementazione basata sulla struttura dati concreta heap [Cap.7.3]. L heap usa il potere gerarchico degli alberi binari per supportare le operazioni della PQ. Consente di migliorare il tempo di esecuzione per algoritmi di ordinamento. L implementazione sul testo è completa. Per motivi di tempo preferisco non mostrarla a lezione. Siete bravi e potete, se volete, vederla da soli (non è nel programma ) 4 Alta priorità come trovarla? Per determinare l elemento con la più alta priorità, occorre trovare un modo (regola) per confrontare le chiavi In altre parole, devo poter Stabilire un criterio di confronto (ossia stabilire un ordine all interno della collezione). Confrontare una qualsiasi coppia di chiavi Relazione di ordine totale ( ) Relazione con le seguenti proprietà Riflessiva: x x Antisimmetrica: x y y x x = y Transitiva: x y y z x z Se si ha una collezione finita di elementi, la relazione d ordine totale consente di ben definire il minimo, ossia l elemento con la chiave più piccola. 5 6 1

Il TDA PriorityQueue Contenitore di oggetti Ogni oggetto è una coppia (key, value) [o anche (chiave, valore)], dove key è la priorità abbinata a value. Metodi principali i insert(k, x) inserisce un oggetto (k, x) [inserisce il valore x con priorità k] removemin() [o anche extractmin()] rimuove l oggetto con chiave (key) più piccola, restituendo in output il suo valore 7 Due domande ancora senza risposta 1. Come si fa ad associare le chiavi ai rispettivi valori? Si usa il design pattern Composition: un singolo oggetto è definito come composizione di altri oggetti 2. Come si confrontano le chiavi in modo da individuare la chiave più piccola? Si usa il design pattern Comparator Faremo una parentesi di Java per ricordare questo design pattern che consente di ordinare oggetti di una qualsiasi classe (anche quando non posso realizzare l interfaccia di Comparable) 8 1. Il design pattern Composition 2. Come confronto le chiavi? Un singolo oggetto è definito come composizione di due o più oggetti 1. Occorre definire una classe che memorizza ciascun oggetto in una sua variabile di istanza e fornisce metodi per accedere e modificare queste variabili Design Pattern Comparator: Fornisce le regole in base alle quali effettuare il confronto delle chiavi (la relazione d ordine totale) 2. E possibile definire composizioni di oggetti costituite da altre composizioni di oggetti in modo da formare una struttura gerarchica basata sulla composizione Vediamo perché public interface Entry { public Object key(); public Object element(); Interfaccia Java per gli oggetti della PQ 9 10 Ci sono diversi modi per confrontare le chiavi 1. Implementare una classe PQ per ciascun tipo di chiave che si vuole usare e per ciascun modo di confrontare ciascun tipo di chiave Problema: non è un metodo generale e richiede di riscrivere molto codice Esempi di confronti A seconda del tipo: consideriamo la chiave 4 e la chiave 11. Possiamo dire che 4<11? Si, se 4 e 11 sono int Se però 4 e 11 sono stringhe confrontate lessicograficamente, allora 11<4! 2. Le chiavi sono istanze di una classe KEY che contiene vari tipologie di confronto Problema: il metodo di confronto dipende dal contesto e potrebbe non essere stato previsto al momento della creazione della classe chiave 11 A seconda dell uso: consideriamo punti p e q nello spazio. Possiamo decidere che chiavi costituite da punti nello spazio possono essere ordinate in base a una qualsiasi delle tre coordinate. Da sinistra a destra (in base alla prima coordinata) (4,5,9) < (8,3,6) Dal basso in alto (in base alla seconda coordinata) (8,3,6) < (4,5,9) 12 2

2.Design Pattern Comparator Ci consente di non fare riferimento alle chiavi per stabilire la regola di confronto. Un oggetto di tipo comparatore è esterno alle chiavi Permette di confrontare due chiavi (i.e., una generica coda a priorità usa un comparatore ausiliario per confrontare due chiavi) Il comparatore viene fornito al momento della costruzione della PQ La PQ può rimpiazzare un comparatore con un nuovo comparatore se diventa obsoleto o si vuole cambiarlo. 13 2. Interfaccia del TDA Comparator public interface Comparator { public int compare(object a, Object b); Se C è un oggetto di tipo comparatore, l invocazione di C.compare(a,b) restituisce un intero i, tale che i<o, se a<b; (a precede b, nell ordinamento) i=0, se a=b; (a e b sono uguali) i>0, se a>b. (a segue b nell ordinamento) C è errore se a e b non sono confrontabili. 14 Classe per rappresentare punti del piano con coordinate intere Vedremo adesso un esempio di comparator per l ordinamento lessicografico di punti del piano. Si tratta anche di un esempio di Composition Pattern public class Point2D { private int xc,yc; //coordinate public Point2D(int x, int y) { xc=x; yc=y; public int getx() { return xc; public int gety() { return yc; 15 16 Ordinamento lessicografico di punti del piano Interfaccia per il TDA PQ public class Lexicographic implements Comparator { int xa, ya, xb, yb; private int compare(object a, Object b) throws ClassCastException { xa = ((Point2D) a).getx(); ya = ((Point2D) a).gety(); xb = ((Point2D) b).getx(); yb = ((Point2D) b).gety(); if (xa!=xb) return (xb-xa); else return (yb-ya); Il metodo di confronto (compare) è definito in modo che sia definita una relazione d ordine totale? 17 public interface PriorityQueue { public int size(); public boolean isempty(); //restituisce il numero di entry della PQ //verifica se la PQ è vuota public Entry min() throws EmptyPQException; //restituisce, senza //rimuovere un oggetto di key minimo public Entry insert(object key, Object value) throws InvalidKeyException; //inserisce una coppia key-value e // restituisce l entry che ha creato public Entry removemin() throws EmptyPQException; //rimuove e // restituisce l entry con key minima. 18 3

Condizioni di errore - eccezioni InvalidKeyException Viene lanciata quando il metodo insert(k,x) è chiamata con una chiave k non valida che non può essere confrontata dal comparatore della PQ (ad esempio, se k è null o k è di una classe non compatibile con la classe delle altre chiavi nella PQ). EmptyPQException Viene lanciata quando si invoca min() oppure removemin() su una PQ vuota Osservazione Si può adesso facilmente intuire che il TDA PQ è più semplice del TDA Sequence. Infatti un oggetto è inserito o rimosso solo in base alle chiavi, non in base alle posizioni o al rango. Quindi nella PQ c è bisogno di un solo metodo per inserire e di un solo metodo per cancellare (mentre il TDA Sequence ne ha di più). 19 20 Esempio di una serie di operazioni su un TDA PQ Operazione Output PQ Insert(5,A) Insert(9,C) Insert(3,B) Insert(7,D) Min() removemin() E1[=(5,A)] E2[=(9,C)] E3[=(3,B)] E4[=(7,D)] E3 E3 {(5,A) {(5,A),(9,C) {(3,B),(5,A),(9,C) {(3,B),(5,A),(7,D)(9,C) {(3,B),(5,A),(7,D)(9,C) {(5,A),(7,D)(9,C) Fa qualcosa in più Applicazioni: ordinare con una PQ Si può usare una coda a priorità per ordinare un insieme di elementi confrontabili. Due fasi: 1. inserisci un elemento alla volta con insert [associo key agli elementi, value è nullo] 2. rimuovi gli elementi uno alla volta con removemin La complessità di tempo di questo algoritmo dipende da come è implementata la PriorityQueue Algorithm PQ-Sort(S,P) Input: sequenza S, e una PQ che confronta chiavi usando la stessa r.o.t. Output: sequenza S ordinata per valori crescenti rispetto alla r.o.t. while (!S.isEmpty ()) e S.removeFirst() P.insert(e, ) while (!P.isEmpty()) e P.removeMin().key() S.insertLast(e) 21 22 Domanda Implementazione PQ con una lista NON ORDINATA COME IMPLEMENTIAMO??? Memorizza gli oggetti (entry) della PQ in una lista L, sulla quale non manteniamo l ordinamento. L è implementata con una lista doppiamente concatenata. Memorizziamo gli oggetti in una lista. Vedremo due realizzazioni, a seconda se vogliamo tenere traccia o no degli oggetti della lista ordinati sulle chiavi. Vantaggi/svantaggi: inserimento veloce, cancellazione lenta. Precisamente, insert(k,x): richiede tempo O(1). Ocorre creare l oggetto e=(k,x) e inserirlo alla fine della lista eseguendo una L.insertLast(e). N.B. Supponiamo che il confronto tra due chiavi è fatto in tempo O(1). 23 min(), removemin(): richiedono tempo O(n). Occorre scorrere tutta la lista per determinare l elemento con chiave minima. 24 4

Implementazione PQ con una lista ORDINATA Memorizza gli elementi della PQ in una lista (implementata come lista a doppi puntatori) per valore di chiave in ordine non decrescente In altre parole, il primo elemento della lista è l entry con la più piccola key. Vantaggi/Svantaggi: cancellazione veloce, inserimento lento. Precisamente: insert(k,x): richiede tempo O(n). Occorre trovare dove inserire l oggetto in modo da mantenere l ordine non decrescente delle chiavi. removemin(), min(): richiedono tempo O(1). la chiave minima è all inizio della lista, posso implementarla attraverso L.remove(L.first()). 25 public class SortedListPriorityQueue implements PriorityQueue protected List L; protected Comparator c; /** Inner class for entries */ protected static class MyEntry implements Entry { protected Object k; // key protected Object v; // value public MyEntry(Object key, Object value) { //costruttore k = key; v = value; // methods of the Entry interface public Object key() { return k; public Object value() { return v; 26 /** Inner class for a default comparator using the natural ordering */ protected static class DefaultComparator implements Comparator { public DefaultComparator() { /* default constructor */ public int compare(object a, Object b) throws ClassCastException { return ((Comparable)a).compareTo(b); 27 /**creazione di una PQ con il default comparator public SortedListPriorityQueue () { L= new NodeList(); c= new DefaultComparator(); /**creazione di una PQ con un dato comparator public SortedListPriorityQueue (Comparator comp){ L= new NodeList(); c= comp; 28 /** Sets the comparator for this priority queue. * @throws IllegalStateException if priority queue is not empty */ public void setcomparator(comparator comp) throws IllegalStateException { public int size() { return L.size(); if (!isempty()) throw new IllegalStateException("Priority queue is not empty"); c = comp; Osservazione: Questo metodo consente di cambiare il comparatore abbinato ad una PQ. Perché è indispensabile che la PQ sia vuota? Vi propongo una possibile risposta (se ne trovate altre, me le dite?): supponiamo di cambiare il comparatore su una PQ non vuota, implementata come lista ordinata (è importante questa ipotesi ). Di fatto sto cambiando il criterio di ordinamento degli elementi; quindi, dopo il setcomparator, la PQ non avrebbe più la proprietà di avere i suoi elementi ordinati secondo il comparatore. 29 public boolean isempty() { return L.isEmpty(); public Entry min() throws EmptyPQException { if (L.isEmpty()) throws EmptyPQException( PQ vuota, non c è minimo ); else return (Entry) L.first().element(); public Entry removemin() throws EmptyPQException { if (L.isEmpty()) throws EmptyPQException( PQ vuota, non c è minimo ); else return (Entry) (L.remove(first())); 30 5

/** Inserts a key-value pair and return the entry created. */ public Entry insert(object k, Object v) throws InvalidKeyException { checkkey(k); // auxiliary key-checking method (could throw exception) Entry entry = new MyEntry(k, v); insertentry(entry); // auxiliary insertion method return entry; /** Auxiliary method that returns the key stored at a given node. */ protected Object key(position pos) { return ((Entry) pos.element()).key(); 31 /** Auxiliary method used for insertion. */ protected void insertentry(entry e) { Object k = e.key(); if (L.isEmpty()) { L.insertFirst(e); // insert into empty list else if (c.compare(k, compare(k key(l.last())) > 0) { L.insertLast(e); // insert at the end of the list else { Position curr = L.first(); while (c.compare(k, key(curr)) > 0) { curr = L.after(curr); // advance toward insertion position L.insertBefore(curr, e); // useful for subclasses 32 Esercizi Completare l implementazione di SortedListPriorityQueue scrivendo il metodo checkkey(k) che controlla se k è una chiave valida Implementare l interfaccia di PQ usando una lista non ordinata (UnsortedListPriorityQueue) Testare i metodi nelle due implementazioni Ritorniamo sull ordinamento con PQ La complessità di tempo di questo algoritmo dipende da come è implementato PriorityQueue: Se usiamo liste non ordinate, abbiamo un O(n) per la prima fase. Ogni removemin richiede un tempo proporzionale al #elementi presenti nella PQ Se usiamo liste ordinate, questo diventa O(n), ma ogni insert diventa proporzionale al #di entry che ci sono nella PQ. Algorithm PQ-Sort(S,P) Input: sequenza S, e una PQ che confronta chiavi usando la stessa r.o.t. Output: sequenza S ordinata per valori crescenti rispetto alla r.o.t. while (!S.isEmpty ()) e S.removeFirst() P.insert(e, ) while (!P.isEmpty()) e P.removeMin().key() S.insertLast(e) 33 34 Ritorniamo sull ordinamento con PQ Se usiamo liste non ordinate di quale algoritmo di ordinamento stiamo parlando??? Selection sort Se usiamo liste ordinate stiamo invece parlando di insertion-sort Algorithm PQ-Sort(S,P) Input: sequenza S, e una PQ che confronta chiavi usando la stessa r.o.t. Output: sequenza S ordinata per valori crescenti rispetto alla r.o.t. while (!S.isEmpty ()) e S.removeFirst() P.insert(e, ) while (!P.isEmpty()) e P.removeMin().key() S.insertLast(e) Selection-Sort Selection-sort è una variante di PQ-sort dove la coda a priorità è implementata con una sequenza non ordinata Tempo di esecuzione di Selection-sort: 1. Inserire gli elementi nella coda richiede n chiamate a insert, e quindi tempo O(n) 2. Rimuovere gli elementi dalla coda in ordine richiede n chiamate a removemin, e quindi tempo proporzionale a: O(n+(n-1) + + 2 +1)= n (n+1) / 2 Selection-sort richiede tempo O(n 2 ) e spazio aggiuntivo O(n) 35 36 6

Insertion-Sort Esercizi proposti Insertion-sort è una variante di PQ-sort dove la coda a priorità è implementata con una sequenza ordinata Tempo di esecuzione di Insertion-sort: 1. Inserire gli elementi nella coda in ordine richiede n chiamate a insert, e quindi tempo proporzionale a: 1 + 2 + + n = n (n+1) / 2 2. Rimuovere gli elementi dalla coda in ordine richiede n chiamate a removemin, e quindi tempo O(n) Implementare PQ-Sort con: UnsortedListPriorityQueue (Selection Sort) SortedListPriorityQueue (Insertion Sort) testare il loro corretto funzionamento. Insertion-sort richiede tempo O(n 2 ) e spazio aggiuntivo O(n) N.B. Il tempo varia a seconda dell input: se la sequenza di input è ordinata al contrario, allora inserisco ogni elemento in testa e quindi ho un O(n). 37 38 7