Handle di Funzioni Versioni recenti di Matlab definiscono in modo pieno il tipo funzione, permetto di assegnare a variabili valori di tipo funzione definire funzioni che ricevono parametri di tipo funzione Valori di tipo funzione denotati da variabili dette handle (riferimento / maniglia)
Handle di Funzioni A un handle possono essere assegnati valori di tipo funzione in due modi 1. Indicando il nome di una funzione esistente (definita dall utente o predefinita) >> seno=@sin ; >> seno(pi/2) ans = 1 2. Mediante la definizione ex novo di una funzione anonima >> sq=@(x)x^2; >> sq(8) ans = 64 >> sq=@(x,y)x^2+2*y; >> d=[1 2 3]; >> sq(2,6) >> sq=@(x,y)sum(x)+2*y; ans = 16 >> sq(d,6) ans = 18
Handle di Funzioni Sintassi di tipo funzione: 1. simbolo @ 2. lista dei parametri di ingresso, tra parentesi tonde 3 espressione che dà il risultato come funzione degli ingressi Se il parametro attuale di una funzione f è di tipo funzione, allora il parametro formale è una handle può essere usato per invocare la funzione passata tramite il parametro La funzione f è una funzione di ordine superiore
Handle di Funzioni Esempio Funzione (di ordine superiore) function [vout]=map(f, vin) applica a tutti gli elementi di vin la funzione f, restituisce la lista dei risultati function [vout]=map(f, vin) for i=1:length(vin) vout(i)=f(vin(i));
Handle di Funzioni Altro esempio Funzione (di ordine superiore) function [x]=acc(f, a, u) applica cumulativamente l operazione binaria f (con elemento neutro u) a tutti gli elementi di a restituisce in x il risultato f(...f( f(u, a(1)), a(2) ).., a(length(a))) Uso di acc function [x]=acc(f, a, u) x=u; for i=1:length(a) x=f(x, a(i)); Funzione (ordinaria) function [s]=sommatoria(a) calcola la sommatoria degli elementi di a function [s]=sommatoria(a) som=@(x,y)x+y; s=acc(som,a,0);
Liste concatenate La lista concatenata è una struttura che organizza i dati in maniera sequenziale. Mentre gli elementi di un array sono accessibili direttamente, gli elementi di una lista devono essere acceduti sequenzialmente: se voglio accedere all i-esimo elemento devo scandire la lista dal primo all (i 1) esimo elemento. Mentre le dimensioni di un array sono rigide, le dimensioni di una lista variano dinamicamente, tramite le operazioni di inserimento e cancellazione di elementi.
Liste concatenate L implementazione di liste può avvenire in vari modi, molto naturale l'uso dei puntatori Inoltre dipe dalle operazioni da svolgere sulla lista Che in MATLAB non esistono Bisogna trovare un altro sistema...
Liste concatenate Operazioni 1. Creazione: crea una lista vuota 2. Inserimento: inserisce un nuovo elemento nella lista. Se fatto in testa alla lista costa O(1) 3. Ricerca: scorre la lista per cercare uno specifico elemento mediante la chiave; se tale elemento esiste, ne ritorna la posizione nella lista 4. Cancellazione: Si ricerca l'elemento da cancellare nella lista, lo si rimuove, si raccordano le due sottoliste 5. Stampa: scorre la lista e ne stampa tutti gli elementi 6. Inserimento in posizione i: Inserisce il nuovo elemento nella posizione i della lista; in coda se i > size
Liste concatenate in Matlab function listobject = lista_concatenata(values) % values è una generica matrice, reshape la vettorizza data = reshape(values,1, []); % 1 prima dimensione, [] per la seconda listobject = struct('display',@display_list,... % handle di funzioni 'addafter', @add_after,... 'delete', @delete_element,... 'search', @search_element,... 'add', @add); function display_list() % definizioni delle funzioni innestate.. function add(key).
Liste concatenate in Matlab function display_list() % visualizza tutti gli elementi della lista for i = 1:length(data) disp(data(i)); function add(values) % aggiunge gli elementi in values (vettore) in testa alla lista data = [values, data]; function add_after(values, index) % aggiunge gli elementi in values (vettore) a partire dalla posizione index, o in coda se index > size index = min(index, length(data)); data = [data(1:index), values, data(index+1:)];
Liste concatenate in Matlab function delete_element(key) % cancella l'elemento di chiave key n = numel(data); for i=1:n if data(i) == key; data(i) = []; % cancella solo il primo trovato break; function res = search_element(key) % cerca l'elemento di chiave key n = numel(data); res = []; for i=1:n if data(i) == key; % se ce n'è più di uno li trova tutti res = [res i];
Struttura dati Pila Pila: insieme di elementi gestiti secondo una politica LIFO (Last In First Out) l ultimo elemento inserito è il primo estratto Dati: una sequenza S di n elementi Operazioni: 1.isEmpty() boolean restituisce true se S è vuota, false altrimenti 2.push(elem e) aggiunge e come ultimo elemento di S 3.pop() elem toglie da S l ultimo elemento e lo restituisce 4.top() elem restituisce l ultimo elemento di S (senza eliminarlo)
Struttura dati Pila function listobject = pila(values) % values è una generica matrice, reshape la vettorizza data = reshape(values,1,[]); listobject = struct('isempty',@pila_vuota,... 'top',@top_elem,... 'push',@push_elem,... 'pop',@pop_elem); function res = pila_vuota() % Displays the data in the list res = numel(data) == 0; function push_elem(key) data = [key data]; function key = top_elem() if ~pila_vuota() key = data(1); else key = -1; %marker value function key = pop_elem() if ~pila_vuota() key = data(1); data = data(2:numel(data)); else key = -1; %marker value % chiude la funzione pila
Coda con priorità Una coda con priorità è una struttura dati che rappresenta insieme finito S di oggetti sul quale è definita una funzione priorità p(s) (esempio l'ordine sulle chiavi) L'elemento con maggiore priorità è sempre in testa alla coda Sulla coda sono definite le seguenti operazioni: 1.MAXIMUM(A): ritorna l elemento a massima priorità, ossia quello in testa. 2.EXTRACT_MAX(A): estrae l elemento con massima priorità, successivamente la coda va sistemata 3.INSERT(A, p): inserisce un nuovo elemento p nella coda.
Coda con priorità Con l'implementazione dello Heap mediante vettore A possiamo realizzare una coda a priorità efficiente MAXIMUM(A) ha un tempo di esecuzione costante, O(1) MAXIMUM(A) return A[1] EXTRACT_MAX(A) ha un tempo di esecuzione O(log(n)), dovuto alla chiamata HEAPIFY. EXTRACT_MAX(A) if heapsize[a] < 1 then error heap underflow max A[1] A[1] A[heapsize[A]] heapsize[a] heapsize[a] 1 HEAPIFY(A,1) return max
Coda con priorità HEAP-INSERT(A, KEY) : Inserisce il nuovo elemento con chiave KEY nella coda (alla fine) e deve far sì che sia rispettata la proprietà della coda. Ha un tempo di esecuzione O(log(n)), nel caso peggiore si risale l albero dalla foglia alla radice. HEAP-INSERT(A, key) heapsize[a] heapsize[a] + 1 i heapsize[a] % inserisce nell'ultimo livello prima posizione da sinistra while i > 1 and A[PARENT(i)] < key % risale finché non trova una chiave >= key do A[i] A[PARENT(i)] i PARENT(i) while A[i] key
Coda con priorità function codaobject = coda_priorita(values) % values è una generica matrice, reshape la vettorizza data = reshape(values,1,[]); heapsize = length(data); data = buildheap(data); codaobject = struct('insert',@insert_codapr,... 'maximum',@maximum,... 'extract_maximum',@extract_maximum,... 'size', @size); function insert_codapr(key) heapsize = heapsize + 1; i = heapsize; while i>1 && data(floor(i/2)) < key data(i) = data(floor(i/2)); i = floor(i/2); data(i) = key;
Coda con priorità function rmax = maximum() if(heapsize >= 1) rmax = data(1); else disp('coda vuota'); function [rmax] = extract_maximum() if(heapsize >=1) rmax = data(1); data(1) = data(heapsize); heapsize = heapsize - 1; data = heapify(data,1,heapsize); else disp('coda vuota'); rmax = 0; function res = size() res = heapsize; % della coda function A = buildheap(a).. function A = heapify(a,i, heapsize)..
Esercizi Esercizio 1. Implementare in MATLAB la struttura dati lista ordinata, una lista concatenata in cui gli elementi sono memorizzati in maniera ordinata (crescente o decrescente) Esercizio 2. Scrivere un programma MATLAB che legge dal file dati.txt dei valori numerici e li inserisce in una pila. Il programma deve fornire poi all'utente 4 possibili funzionalità: 1. Inserire un nuovo valore 2. Visualizzare l'elemento in cima alla pila 3. Estrarre un valore 4. Controllare che ci siano elementi Il programma deve uscire solo quando l'utente digita 'esci'
Esercizi Esercizio 3. Scrivere un programma MATLAB che riceve le richieste di sussidio e le memorizza in una coda a priorità. Ogni richiesta è formata da nome (stringa) e da un indicatore economico (scalare) che rappresenta anche la priorità della richiesta. Il programma deve fornire poi all'utente 4 possibili funzionalità: 1. Inserire una nuova richiesta 2. Visualizzare il numero di richieste esistenti 3. Estrarre la richiesta con minimo indicatore economico 4. Visualizzare la richiesta con minimo indicatore Il programma deve uscire solo quando l'utente digita 'esci' Esercizio 4. Implementare una versione della coda con priorità che utilizza un vettore, anziché uno heap, per implementare le operazioni richieste. Confrontare i tempi di esecuzione delle due versioni di coda con 49500 operazioni di inserimento e 50000 operazioni di estrazione del massimo parto da una coda con 1000 elementi.