Tavole dinamiche Spesso non si sa a priori quanta memoria serve per memorizzare dei dati in un array, in una tavola hash, in un heap, ecc. Può capitare.

Slides:



Advertisements
Presentazioni simili
Puntatori e gestione dinamica della RAM
Advertisements

Strutture dati per insiemi disgiunti
1 La Standard Template Library vettori, liste, mappe, …. find, replace, reverse, sort, …. puntatori intelligenti La libreria standard STL e una libreria.
Tecnologia delle basi di dati: Strutture fisiche di accesso
Tipi di dato astratti Lista, Pila, Coda, Albero.
Strutture dati lineari
File System Cos’è un File System File e Directory
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
Liste di Interi Esercitazione. Liste Concatenate Tipo di dato utile per memorizzare sequenze di elementi di dimensioni variabile Definizione tipicamente.
LIP: 1 Marzo 2005 Classe Object e Vettori. Partiamo da Lesercizio dellultima esercitazione realizzato tramite array Vedremo come si puo fare in modo piu.
Fondamenti di Informatica I CDL in Ingegneria Elettronica - A.A CDL in Ingegneria Elettronica - A.A Strutture dati dinamiche.
Algoritmi e Strutture Dati
UD 3: “Le Liste” UD 4: “Pile e Code” UD 5: “Alberi e grafi”
Lez. 71 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Gestione Dinamica.
RB-alberi (Red-Black trees)
Hash Tables Indirizzamento diretto Tabelle Hash
Hash Tables Indirizzamento diretto Tabelle Hash Risoluzioni di collisioni Indirizzamento aperto.
Code a priorità (Heap) Definizione
Strutture dati elementari
Alberi binari di ricerca
Indirizzi delle variabili A ogni variabile sono associati tre concetti fondamentali: il valore memorizzato; il tipo dati di appartenenza; lindirizzo. Il.
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Process synchronization
U V U V (a) |cfc|=2 prima e dopo (b) |cfc|=2 prima e |cfc|=1 dopo
1 Strutture dati avanzate Vedremo alcune strutture dati che permettono di eseguire in modo particolarmente efficiente un determinato insieme di operazioni.
Il problema del dizionario
Capitolo 7 Tavole hash Algoritmi e Strutture Dati.
Interrogazioni su un albero binario di ricerca Search(S,k) – dato un insieme S ed un valore chiave k restituisce un puntatore x ad un elemento in S tale.
Capitolo 7 Tavole hash Algoritmi e Strutture Dati.
Laboratorio di Linguaggi lezione V Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea in.
Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.
Laboratorio di Linguaggi lezione IV Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea in.
07/04/2003Algoritmi Ricerca in una sequenza di elementi Data una sequenza di elementi, occorre verificare se un elemento fa parte della sequenza oppure.
Algoritmi e Strutture Dati
Heap allocation e garbage collector di Oberon Algoritmo Quick Fit e garbage collector mark and sweep.
Heap binomiali Gli heap binomiali sono strutture dati su cui si possono eseguire efficientemente le operazioni: Make(H) : crea uno heap vuoto Insert(H,
memoria gestita staticamente:
1 Programmazione = decomposizione basata su astrazioni (con riferimento a Java)
Anche la RB-Delete ha due fasi: Nella prima viene tolto un nodo y avente uno dei sottoalberi vuoto sostituendolo con la radice dellaltro sottoalbero. Per.
Metodo della moltiplicazione
Esercizio 10.* Un cassiere vuole dare un resto di n centesimi di euro usando il minimo numero di monete. a) Descrivere un algoritmo goloso per fare ciò.
1 ListaDiElem Cancella( ListaDiElem lista, TipoElemento elem ) { ListaDiElem puntTemp; if( ! ListaVuota(lista) ) if( lista–>info == elem ) { puntTemp =
Strutture dati per insiemi disgiunti
Radix-Sort(A,d) // A[i] = cd...c2c1
15 maggio 2002 Avvisi: Ultima lezione: mercoledì 29 maggio II Esonero: mercoledì 5 giugno, ora da stabilire.
Vedremo in seguito che (n log n) è un limite stretto per il problema dellordinamento. Per ora ci limitiamo a dimostrare che: La complessità nel caso pessimo.
Ispezione lineare La funzione hash h(k,i) si ottiene da una funzione hash ordinaria h'(k) ponendo L’esplorazione inizia dalla cella h(k,0) = h'(k) e continua.
RB-insert(T, z) // z.left = z.right = T.nil Insert(T, z) z.color = RED // z è rosso. Lunica violazione // possibile delle proprietà degli alberi // rosso-neri.
Per valutare la complessità ammortizzata scomponiamo ogni Union: nelle due FindSet e nella Link che la costituiscono e valuteremo la complessità in funzione.
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti dispense prof. G. Levi.
Corso JAVA Lezione n° 11 Istituto Statale di Istruzione Superiore “F. Enriques”
Complessità di un algoritmo
Capitolo 7 Tavole hash Algoritmi e Strutture Dati Camil Demetrescu, Irene Finocchi, Giuseppe F. Italiano.
Valutare la difficoltà dei problemi
Implementazione di dizionari Problema del dizionario dinamico Scegliere una struttura dati in cui memorizzare dei record con un campo key e alcuni altri.
1 Gestione della Memoria. 2 Idealmente la memoria dovrebbe essere –grande –veloce –non volatile Gerarchia di memorie –Disco: capiente, lento, non volatile.
Heap concetti ed applicazioni. maggio 2002ASD - Heap2 heap heap = catasta condizione di heap 1.albero binario perfettamente bilanciato 2.tutte le foglie.
Esercitazione su Vector. Permette di definire collezioni di dati generiche, che sono in grado di memorizzare elementi di ogni sottotipo di Object Definito.
Risoluzione delle collisioni con indirizzamento aperto Con la tecnica di indirizzamento aperto tutti gli elementi stanno nella tavola. La funzione hash.
Algoritmi e Strutture Dati Strutture Dati Elementari.
Ordinamento in tempo lineare Il limite inferiore Ω(n log n) vale per tutti gli algoritmi di ordinamento generali, ossia per algoritmi che non fanno alcuna.
Relazione sulle strutture dati Svolta da: Buccella Simone Strutture di dati Aree di memoria Puntatore numericibooleani alfabetici Statici dinamici Puntatori.
Liste Concatenate 11 Aprile E’ una delle strutture dati fondamentali in tutti i linguaggi di programmazione di alto livello Una Lista Concatenata.
1 Analisi ammortizzata Si considera il tempo richiesto per eseguire, nel caso pessimo, una intera sequenza di operazioni. Se le operazioni costose sono.
1 Strutture dati. 2 Astrazione Non vogliamo sapere l’organizzazione fisica dei dati  indirizzi e celle di memoria Ci interessa solo la loro organizzazione.
LIP: 15 Marzo 2005 Vettori di interi. Esercizio proposto Definire una classe VectorInt i cui oggetti sono vettori omogenei di interi ordinati in modo.
Algoritmi e Strutture Dati HeapSort. Select Sort: intuizioni L’algoritmo Select-Sort  scandisce tutti gli elementi dell’array a partire dall’ultimo elemento.
Corso di Algoritmi e Strutture Dati con Laboratorio Java Collections Framework (II parte)
1 MODULO STRUTTURE DATI FONDAMENTALI: Strutture dinamiche classe 4° INDUSTRIALE INFORMATICA Focus on.
Transcript della presentazione:

Tavole dinamiche Spesso non si sa a priori quanta memoria serve per memorizzare dei dati in un array, in una tavola hash, in un heap, ecc. Può capitare quindi di aver allocato una certa quantità di memoria per poi accorgersi, durante l’esecuzione del programma, che non ci basta. In tal caso bisogna allocare una memoria maggiore, ricopiare il contenuto della vecchia memoria nella nuova e rilasciare la vecchia memoria.

E’ anche opportuno, dopo aver rimosso molti elementi, ridurre la memoria allocando una memoria più piccola in cui memorizzare gli elementi rimasti. Vedremo come sia possibile aggiungere e togliere un elemento dalla tavola in tempo ammortizzato costante O(1) benché tali operazioni abbiano costo maggiore quando comportano espansione o riduzione della memoria. Vedremo anche che questo si può fare garantendo che la memoria inutilizzata sia sempre inferiore ad una frazione costante della memoria allocata.

Supporremo che una tavola T abbia i seguenti attributi: un puntatore T.table alla memoria allocata. due campi interi T.num e T.size, rispettivamente il numero di elementi presenti nella tavola e la dimensione della tavola. In C++ se V è un vector V.size è num V.capacity è size (la memoria allocata) V.max_size è la massima memoria allocabile

Supporremo inoltre che sia possibile riservare e rilasciare memoria con le due operazioni: Allocate(n) che riserva memoria per n elementi e restituisce un puntatore a tale memoria. Free(p, n) che rilascia la memoria di dimensione n puntata da p.

Le operazioni da realizzare sono: Table(T) che crea una nuova tavola vuota T. Insert(T, x) che inserisce l’oggetto x nella tavola T. Delete(T, x) che rimuove l’oggetto x dalla tavola T.

Non ci cureremo di come gli elementi siano organizzati nella memoria allocata o di altri dettagli implementativi ma ci limiteremo ad assumere che siano definite le tre operazioni: Push(p, x) memorizza l’elemento x nella memoria puntata da p. Pop(p, x) rimuove l’elemento x dalla memoria puntata da p. Copy(q, p, n) ricopia n elementi dalla memoria puntata da p alla memoria puntata da q.

Espansione Consideriamo dapprima il caso in cui vengono eseguite soltanto inserzioni di nuovi elementi e nessuna rimozione. Definiamo come fattore di carico della tavola il rapporto α = num / size. Quando α = 1 la tavola è piena ed occorre espanderla allocando nuova memoria. Una euristica comune è raddoppiare la memoria, il che garantisce un fattore di carico α > ½.

La definizione della funzione Table(T) che crea una tavola vuota è: T.size = 0 T.num = 0 T.table = nil Essa richiede un tempo costante.

La definizione di Insert(x) è: Insert(T,x) if T.size == 0 T.table = Allocate(1) T.size = 1 if T.num == T.size p = Allocate(2 T.size) Copy(p, T.table, T.num) Free(T.table, T.size) T.table = p T.size = 2 T.size Push(T.table, x) T.num = T.num + 1

Per l’analisi di Insert possiamo assumere che le operazioni Allocate, Free e Push richiedano tempo costante e che Copy richieda tempo proporzionale al numero di elementi copiati. Consideriamo il costo di una sequenza di n Insert eseguite a partire da una tavola vuota. Il costo della k-esima Insert è 1 se non vi è espansione ed è k se vi è espansione: k-1 per copiare i k-1 elementi precedenti più 1 per le altre operazioni.

Siccome T.size è sempre una potenza di 2 e l’espansione si ha quando T.num = k-1 è uguale a T.size, il costo della k-esima Insert è: e il costo totale di n Insert è: Insert ha quindi costo ammortizzato: O(3n)/n = O(1)

Il metodo degli accantonamenti mostra perchè il costo ammortizzato è 3. una unità di costo viene spesa subito per l’inserimento dell’elemento stesso. una viene attribuita come credito all’elemento stesso per pagare la sua successiva ricopiatura. la terza viene attribuita come credito ad un altro elemento ricopiato prima e rimasto privo di credito. Quindi, al momento dell’espansione, ogni elemento ha una unità di costo per pagarsi la ricopiatura.

Possiamo anche usare il metodo del potenziale scegliendo una funzione potenziale Φ che vale 0 all’inizio e subito dopo una ricopiatura e che cresce fino alla dimensione della tavola tra una espansione e la successiva. Una tale funzione è: Subito dopo la ricopiatura: Quando la tavola è piena:

4 2 1 8 16 32 i num size 2 num-size

Il costo ammortizzato di un inserimento senza espansione è: con espansione ĉ1 = 2 (tavola vuota) e per k > 1

Espansione e contrazione Delete(x) si realizza con una Pop(T.table, x) che rimuove l’elemento x dalla tavola. Ad evitare uno spreco eccessivo di memoria è opportuno contrarre la tavola quando il fattore di carico α = num / size diventa troppo piccolo. Questo si fa allocando una memoria più piccola, ricopiando i T.num elementi presenti nella tavola, e rilasciando la vecchia memoria.

La strategia ovvia è dimezzare la memoria quando il fattore di carico α diventa ≤ 1/2. Questo ci assicura un fattore di carico α > 1/2 anche in presenza di Delete. Purtroppo, con questa strategia il costo ammortizzato delle operazioni non è più costante.

Consideriamo una successione costituita da 2k Insert seguite da 2k-2 gruppi di quattro operazioni Insert - Delete - Delete - Insert per un totale di n = 2k+1 operazioni. In ogni gruppo la prima Insert comporta una espansione di costo 2k e la seconda Delete una contrazione di costo 2k. Quindi ogni gruppo ha costo ≥ 2k+1 e in totale i 2k-2 gruppi hanno costo: ≥ 2k-2 2k+1 = n2/8 = Ω(n2) e il costo ammortizzato è Ω(n2)/n = Ω(n).

Il problema è che dopo una espansione (che porta α ad 1/2 e consuma tutti i crediti) non si eseguono rimozioni sufficienti ad accumulare crediti per la successiva contrazione. Occorre quindi aspettare che sia stata rimossa almeno una metà degli elementi, ossia che α diventi 1/4.

La definizione della funzione Delete(x) è: Delete(T, x) if T.num ≤ T.size / 4 p = Allocate(T.size / 2) Copy(p, T.table, T.num) Free(T.table, T.size) T.table = p T.size = T.size / 2 Pop(T.table, x) T.num = T.num - 1

Usiamo il metodo del potenziale con una funzione potenziale  che vale 0 sia all’inizio che subito dopo una espansione o contrazione e che cresce fino a raggiungere il numero di elementi presenti nella tavola quando il fattore di carico α aumenta fino ad 1 o diminuisce fino ad 1/4. Una funzione di questo tipo è

4 2 1 8 16 32 i num size 48

Se α ≥ 1/2 il costo ammortizzato di un inserimento senza espansione è: con espansione; ĉ1 = 2 (tavola vuota) e per k > 1:

Se α < 1/2 non vi è sicuramente espansione e il costo ammortizzato di un inserimento è:

Se α ≤ 1/2 il costo ammortizzato di una rimozione senza contrazione è: mentre con contrazione è:

Se α > 1/2 non vi è sicuramente contrazione e il costo ammortizzato di una rimozione è:

Esercizio 16 Assumere che la contrazione della tavola dinamica venga effettuata quando α = 1/3 invece che quando α = 1/4 e che invece di ridurre la sua dimensione ad 1/2 size essa venga ridotta a 2/3 size. Calcolare il costo ammortizzato delle operazioni usando la funzione potenziale:  = |2 num - size|