Scaricare la presentazione
La presentazione è in caricamento. Aspetta per favore
PubblicatoArabella Fabbri Modificato 10 anni fa
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 individuare le 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 ricerca sequenziale a patto che l’elenco di input sia stato precedentemente ordinato L’algoritmo di ricerca binaria impiega sino a log(n) confronti per individuare un 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 elem l’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 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] Dove si trovano i log(n) confronti dell’algoritmo di ricerca binaria???
5
Ricerca binaria 192425 262728 2921 0631742859 Problema 1: Ricercare l’elemento 26 all’interno del vettore A[0…9] 262728 29 67859 Problema 2: Ricercare l’elemento 26 all’interno del vettore A[5…9] 2627 65 Problema 3: Ricercare l’elemento 26 all’interno del vettore A[5…6] Risposta problema 3: L’elemento si trova alla posizione 5! Risposta problema 2: L’elemento si trova alla posizione 5! Risposta problema 1: 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
E’ possibile implementare una procedura ricorsiva in C/C++ attraverso le chiamate a funzione PosizioneElemento invoca se stessa quando la taglia dell’elenco in input è diversa da zero (condizione di ricorsione) PosizioneElemento termina quando la taglia dell’elenco in input è zero (condizione di terminazione) 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 */ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
8
Ricerca binaria Sia dato in input il vettore Voti[0…9] e l’elemento 26 PosizioneElemento(0,9,Voti,26) L’elemento centrale (Voti[4]) è minore dell’elemento cercato, proseguiamo la 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 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 */ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
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(x 1,…,x n-1,x n ) if (n > 2) return Somma(x 1,…,x n-1 ) + x n else if (n == 2) return x 1 + x 2 else return x 1
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) = Somma(7,3,9) + 6 = Somma(7,3,9) = Somma(7,3) + 9 = Somma(7,3) = 7 + 3 = 25 +2 19 + 6 = 25 10 + 9 = 19 10 Somma(7,3,9,6,2)
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 Fib(5) Fib(4) Fib(3) Fib(1)Fib(2) Fib(1)Fib(0) Fib(3) Fib(1)Fib(2) Fib(0)Fib(1) Fib(2) Fib(0)Fib(1) Calcolare il numero di Fibonacci associato a 5
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 2 n
17
Numeri Fibonacci – strategia iterativa Fib(5) Fib(4) Fib(3) Fib(2) Fib(1) Fib(0) Introduciamo un array Fib di taglia n per memorizzare il valore dei numeri di Fibonacci già calcolati Sia dato un numero x in input (e.g., 5) Calcoleremo il numero di Fibonacci associato ad x a partire dagli elementi più piccoli, memorizzando e riutlizzando i valori già calcolati
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?
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.