1 / 18

Sistemi e Tecnologie Informatiche

Sistemi e Tecnologie Informatiche. Ricorsione. Umberto Ferraro Petrillo. Nella lezione precedente …. … abbiamo imparato che: E’ possibile adoperare l’algoritmo di ricerca sequenziale per individuare le occorrenze di un elemento all’interno di una lista

tracen
Download Presentation

Sistemi e Tecnologie Informatiche

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Sistemi e Tecnologie Informatiche Ricorsione Umberto Ferraro Petrillo

  2. Nella lezione precedente … • … abbiamo imparato che: • E’ possibile adoperare l’algoritmo di ricerca sequenziale per individuarele occorrenze di un elemento all’interno di una lista • Tale algoritmo può rivelarsi estremamente inefficiente poichè richiede sino ad n confronti (dove n è pari alla taglia della lista) per individuare un elemento • L’algoritmo di ricerca binaria migliora le prestazioni dell’algoritmo di ricercasequenziale a patto che l’elenco di input sia stato precedentemente ordinato • L’algoritmo di ricerca binaria impiega sino a log(n) confronti per individuareun elemento

  3. In questa lezione … • … impareremo che: • L’algoritmo di ricerca binaria adotta una strategia risolutiva che può essere applicata anche ad altri problemi e che va sotto il nome di ricorsione • Esistono differenti tipi di ricorsione • Non sempre l’approccio ricorsivo è quello migliore

  4. Mistero … Cerca elem nel vettore Voti[0 … n-1] Sia Voti l’elenco di input, n la taglia dello stesso ed eleml’elemento cercato Sia i l’indice dell’elemento attualmente considerato, inizialmente i = 0 Ripeti per n-1 volte o fino a che Voti[i] è uguale ad elem Considera il prossimo elemento (i=i+1) Se Voti[i] è uguale ad elem restituisci i altrimenti restituisci -1 Dove si trovano i log(n)confronti dell’algoritmodi ricerca binaria??? Cerca elem nel vettore ordinato Voti[inf … sup] Se l’array è vuoto (inf>sup) la ricerca termina (ritorna -1) Considera l’elemento nella posizione centrale (med=(inf+sup)/2) Se elem è uguale a Voti[med] la ricerca termina (ritorna med) Altrimenti, se elem è minore di Voti[med] cerca elem nel vettore Voti[inf … med -1] Altrimenti, cerca elem nel vettore Voti[med+1 … sup]

  5. 0 1 2 3 4 5 6 7 8 9 19 21 24 25 25 26 27 28 28 29 Ricerca binaria Problema 1: Ricercare l’elemento 26 all’interno del vettore A[0…9] Risposta problema 1: L’elemento si trova alla posizione 5! Problema 2: Ricercare l’elemento 26 all’interno del vettore A[5…9] 5 6 7 8 9 26 27 28 28 29 Risposta problema 2: L’elemento si trova alla posizione 5! Problema 3: Ricercare l’elemento 26 all’interno del vettore A[5…6] 5 6 26 27 Risposta problema 3: L’elemento si trova alla posizione 5!

  6. Procedure ricorsive • L’algoritmo di ricerca binaria è un tipico esempio di procedura ricorsiva • Una procedura si dice ricorsiva quando all’interno della sua definizione compare un riferimento alla procedura stessa (e.g. La funzione PosizioneElemento(0,9,Voti,22) esegue al suo interno la funzione PosizioneElemento(0,4,Voti,22)) • Affinchè l’esecuzione di una procedura ricorsiva finisca è prevista l’esistenza di una condizione di terminazione (e.g. La ricerca binaria di un elemento si arresta quando l’array è vuoto) • La ricorsione ci consente la risoluzione di problemi complessi a parte da problemi più elementari

  7. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 int PosizioneElemento(int inf, int sup, int Voti[], int elem) { /* Effettua la ricerca binaria di elem tra i primi n elementi di Voti. Il valore di ritorno e` -1 se elem non e` presente in Voti, altrimenti e` l'indice della posizione di elem. */ if ( inf>sup) // Verifichiamo se esistono elementi da considerare return -1; else{ int med = (int) (inf + sup) / 2; if (Voti[med] == elem) return med; // L’elemento è stato individuato else if (elem < Voti[med]) { sup = med -1; // Cerchiamo nella porzione di sinistra return PosizioneElemento(inf, sup, Voti, elem); } else{ inf = med + 1; // Cerchiamo nella porzione di destra return PosizioneElemento(inf, sup, Voti, elem); } } } /* PosizioneElemento */ • E’ possibile implementareuna procedura ricorsivain C/C++ attraverso lechiamate a funzione • PosizioneElemento invocase stessa quando la tagliadell’elenco in input èdiversa da zero(condizione di ricorsione) • PosizioneElementotermina quando la tagliadell’elenco in input èzero(condizione di terminazione)

  8. Ricerca binaria Sia dato in input il vettore Voti[0…9] e l’elemento 26 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 int PosizioneElemento(int inf, int sup, int Voti[], int elem) { if ( inf>sup) // Verifichiamo se esistono ancora elementi return -1; else{ int med = (int) (inf + sup) / 2; if (Voti[med] == elem) return med; // L’elemento è stato individuato else if (elem < Voti[med]) { sup = med -1; // Cerchiamo nella porzione di sinistra return PosizioneElemento(inf,sup,Voti, elem); } else{ inf = med + 1; // Cerchiamo nella porzione di destra return PosizioneElemento(inf, sup, Voti, elem); } } } /* PosizioneElemento */ PosizioneElemento(0,9,Voti,26) L’elemento centrale (Voti[4]) è minoredell’elemento cercato, proseguiamola ricerca in Voti[5…9] PosizioneElemento(5,9,Voti,26) L’elemento centrale (Voti[7]) è maggiore dell’elemento cercato, proseguiamo la ricerca in Voti[5…6] PosizioneElemento(5,9,Voti,26) L’elemento centrale (Voti[5]) è uguale all’elemento cercato, restituiamo il suo indice 5

  9. Ricorsione • Esistono due tipi di ricorsione: • Ricorsione diretta: All’interno della procedura A compare esplicitamente la chiamata a se stessa • Ricorsione indiretta • All’interno della procedura A viene invocata una seconda procedura B che a sua volta invoca A

  10. Ricorsione diretta • Immaginiamo di disporre di un computer capace di sommare solo due valori per volta • Problema: Scrivere una funzione ricorsiva Somma capace di addizionare un numero arbitrario di valori • Osservazione: Somma(x,y,z,w) = Somma(x,y,z) + w • Algoritmo risolutivo: Somma(x1,…,xn-1,xn)if (n > 2) return Somma(x1,…,xn-1) + xnelse if (n == 2) return x1 + x2else return x1

  11. Ricorsione diretta • La funzione Somma sa addizionare esclusivamente due numeri • Se i valori da sommare sono n, con n maggiore di 2, si sommano “a parte” i primi n-1 numeri, il totale viene sommato al numero n-simo Somma(7,3,9,6,2) = Somma(7,3,9,6) + 2 = 25 +2 Somma(7,3,9,6) = Somma(7,3,9) + 6 = 19 + 6 = 25 Somma(7,3,9) = Somma(7,3) + 9 = 10 + 9 = 19 10 Somma(7,3) = 7 + 3 =

  12. Ricorsione indiretta • Immaginiamo di disporre di un calcolatore incapace di operare divisioni • Problema: Ideare una funzione ricorsiva Pari capace di dirci se un numero è pari o meno • Osservazione: x è pari se e solo se x-1 è dispari • Algoritmo risolutivo: Pari(x)if x == 0 return true else return Dispari(x-1) Dispari(y)if y == 0 return false else return Pari(x-1)

  13. Ricorsione indiretta • Dato x in input, la funzione Pari restituisce vero se e soltanto se la funzione Dispari(x-1) restituisce vero • Dato y in input, la funzione Dispari restituisce vero se e soltanto se la funzione Pari(y-1) restituisce vero • Pari(0) restituisce vero • Dispari(0) restituisce falso Pari(5) è vero se e solo se Dispari(4) è vero Dispari(4) è vero se e solo se Pari(3) è vero Pari(3) è vero se e solo se Dispari(2) è vero Dispari(2) è vero se e solo se Pari(1) è vero Pari(1) è vero se e solo se Dispari(0) è vero Dispari(0) è falso

  14. Numeri Fibonacci • I numeri di Fibonacci provengono da una successione numerica definita dalla seguente relazione: • Fib(n) = Fib(n-1) + Fib(n-2) • Fib(0) = 1 • Fib(1) = 1 E.g., Fib(2) = Fib(1) + Fib(0) = 1 + 1 = 2 Fib(6) = Fib(5) + Fib(4) = Fib(4) + Fib (3) + Fib(4) = … = 13

  15. Numeri Fibonacci Calcolare il numero di Fibonacci associato a 5 Fib(5) Fib(4) Fib(3) Fib(1) Fib(2) Fib(2) Fib(3) Fib(0) Fib(1) Fib(0) Fib(1) Fib(1) Fib(2) Fib(0) Fib(1)

  16. Numeri Fibonacci • La strategia ricorsiva non sempre è quella migliore • Nel caso dei numeri di Fibonacci essa si rivela inefficace poichècostringe a ricalcolare numerose volte gli stessi risultati • Il numero di esecuzioni della procedura Fibonacci calcolata sul valore n è circa 2n

  17. Numeri Fibonacci –strategia iterativa • Introduciamo un array Fib di taglia n per memorizzare ilvalore dei numeri di Fibonacci già calcolati • Sia dato un numero x in input (e.g., 5) • Calcoleremo il numero di Fibonacci associato ad x apartire dagli elementi più piccoli, memorizzando eriutlizzando i valori già calcolati Fib(5) Fib(4) Fib(3) Fib(2) Fib(1) Fib(0)

  18. Esercizio • Immaginiamo di disporre di un calcolatore capace esclusivamente di sommare o sottrarre 1 ad un qualsiasi valore numerico • Problema: Come è possibile implementare la somma di una coppia di numeri qualsiasi? • E.g., • 22 + 49?

More Related