nikpez
Ominide
8 min. di lettura
Vota 2,5 / 5

Concetti Chiave

  • Recursion is a method of solving problems by breaking them into smaller, similar subproblems, using functions that call themselves.
  • Recursive definitions are used in various contexts, including algorithms and data structures like lists and trees.
  • The principle of mathematical induction is a technique to prove propositions for all natural numbers, relying on a base case and an inductive step.
  • Recursive algorithms, such as calculating factorials or the greatest common divisor (GCD), often involve a base case and recursive case to simplify the problem.
  • The Fibonacci sequence is an example of a problem that can be defined recursively, demonstrating the power of finite descriptions for infinite sets.
La ricorsione

Iterare è
umano, usare
la ricorsione
divino.
(Anonimo)

Introduzione
Problema: Si consideri il problema di dover versare la somma di 16,51€ con il minor numero possibile di pezzi, tra banconote e monete.
Soluzione: Il problema può essere suddiviso in due sottoproblemi: versare 10,00€ e versare 6,51€ Il primo sottoproblema può essere subito risolto con una banconota da 10,00€, mentre il secondo sottoproblema è molto simile al problema di partenza, ad eccezione del fatto che la somma da versare è più piccola.
La ricorsività è semplicemente il processo per risolvere un problema riducendolo in sottoproblemi che sono:
Identici in struttura al problema originale
Un po’ più semplice da risolvere.
Una funzione è detta ricorsiva quando direttamente (ricorsione semplice) o indirettamente (ricorsione mutua) chiama se stessa.
Ricorsione dal latino re - currere (ricorrere, fare ripetutamente la stessa azione).
Il concetto di ricorsione viene usato nel contesto di:
- Algoritmi
- Strutture dati (liste, alberi, …)

Principio di induzione
Il termine ricorsione indica la possibilità in una definizione di far ricorso alla definizione stessa (definizione ricorsiva).
Definizione ricorsiva (o per induzione) dei numeri naturali N:
- 0 è un numero naturale
- se n è un numero naturale, allora n+1 è un numero naturale.
Consideriamo un enunciato o proposizione che contenga come parametro un numero
naturale n e la indichiamo genericamente con P(n).
- Ci chiediamo se P(n) sia vera o falsa.
- Eulero (1707-1783,matematico e fisico svizzero) ha proposto lo studio dei valori del trinomio n2 + n + 41.
E’ ingenuo ritenere che una certa P(n) sia vera per tutti gli n se è vera solo per alcuni.
- Data una P(n) basta un contro-esempio per concludere che è falsa.
- Per dimostrare che P(n) è vera non bastano 10, 100, 1000… verifiche.
Il principio di induzione (matematica) è una tecnica per dimostrare che una famiglia di proposizioni P(n) è vera per ogni n appartenente a N.
Principio di induzione: sia P(n) un enunciato parametrizzato rispetto ad un numero naturale n.
Dalla verità dei seguenti due enunciati:
- Base di induzione: P(0) è vero;
- Passo induttivo: detto n un generico numero naturale, se P(n) è vero (ipotesi di induzione) allora anche P(n+1) è vero;
si deduce che P(n) è vero per ogni n appartenente a N.

Definizioni ricorsive
Definizione ricorsiva (o per induzione) di fattoriale di un numero naturale n.
- 0! = 1 (chiusura della ricorsione/base di induzione)
- n! = n (n - 1)! (passo ricorsivo/passo induttivo)
Definizione iterativa di fattoriale: il fattoriale di n è il prodotto dei numeri naturali compresi tra 1 ed n.
Giustificazione della posizione 0!=1
n! = 1 * 2 * 3 * … * n per n >=1
n+1)! = (n+1)n!
Per n = 0, sostituendo si ha:
1! = 1*0! => 0! = 1/1 = 1
Definizione ricorsiva della potenza di un numero a ≠ 0.
a^n = 1 se n = 0
a^n = a*an-1 se n > 0
Giustificazione che a 0 = 1
a^n = a * a * … * a (n fattori)
a^n+1 = a * an
per n = 1, a^2 = a * a^1 => a^1 = a*a/a = a
per n = 0, a^1 = a * a^0 => a^0 = a/a = 1

La programmazione ricorsiva
Una funzione è detta ricorsiva quando direttamente (ricorsione semplice) o indirettamente (ricorsione mutua) chiama se stessa.
- Ricorsione dal latino re-currere (ricorrere, fare
ripetutamente la stessa azione).
- Il concetto di ricorsione viene usato nel contesto di:
1) Algoritmi
2) Strutture dati (liste, alberi, …).

Prima funzione ricorsiva: fattoriale
unsigned long fatt (unsigned int n)
{if ( n == 0)
return 1;
else
return n*fatt (n-1);}

Calcoliamo fatt(3), indicando passo passo le operazioni che vengono eseguite dal
sistema e che rimangono nascoste al programmatore.

Fatt(3) = 3 * fatt(2) = 3*2*fatt(1) = 3*2*1 *fatt(0)= 3*2*1*1 = 6

- Nel “ramo allora” troviamo la condizione di chiusura delle chiamate successive.
- Nel “ramo altrimenti” troviamo la definizione vera e propria che ha la forma di una nuova chiamata di se stessa fatt(n-1).
- L’algoritmo decrementa il valore di n fino a 0, conservando in un apposito spazio di memoria, in pila uno sull’altro, i valori successivi del parametro n fino al valore 0. In questa fase di chiamate ricorsive non viene eseguito alcun calcolo; non appena n = 0 vengono eseguiti i calcoli a ritroso secondo i valori di n prelevati dalla pila, in ordine inverso rispetto a quello dell’immissione.

Osservazioni
- E’ importante notare come i valori di n vengono modificati ad ogni chiamata, mentre la pila (STACK) consente di non perdere i valori precedenti.
- Nei linguaggi che consentono la ricorsione questa gestione è un fatto interno al sistema della quale il programmatore non si deve curare.
- La traccia indicata consente una verifica sulla correttezza delle funzioni/procedure ricorsive adottate ed è un aiuto al programmatore all’atto della verifica di un pgm.
La convenienza nell’uso dello STACK è che le procedure terminano in ordine inverso a quello di attivazione e che quindi i record stessi seguono la medesima
sorte.
- Scrivere una funzione C che calcoli il MCD fra due interi a e b con il metodo ricorsivo della sottrazione.
MCD(a,b) = a se a = b
MCD(a,b)=MCD(a-b,b) se a > b
MCD(a,b)=MCD(b-a,a) se a

int mcd (int a, int b)
{
if(a == b)
return a;
else if (a > b)
return mcd(a-b,b);
else
return mcd(b-a,a);
}

Esercizio
Calcolare il MCD fra 4 interi, scrivere una sola istruzione.

int risult=mcd(mcd(a,b),mcd(c,d));

Osservazione
- E’ buona norma ricordare le regole applicate nella formulazione degli alg. ricorsivi, in quanto condizioni necessarie non sufficienti per ottenere la correttezza, precisamente:
1. Deve essere sempre presente la condizione di chiusura della ricorsione.
2. Ogni successiva chiamata deve riferirsi a valori minori di quello di partenza o ad un sottoinsieme dell’insieme originale di elementi.

Lo “spirito” del metodo ricorsivo
- Esiste un CASO BASE, rappresentante un sotto-problema facilmente risolubile.
- Per es.,nel caso del fattoriale, se n=0 so calcolare il fattoriale di n,vale 1.
- Negli altri casi ci si deve ricondurre al caso base.

Numeri di Fibonacci (1170-1250, matematico italiano(PISA))
- La potenza di una definizione ricorsiva è legata alla possibilità di definire un insieme di oggetti infinito mediante una descrizione finita.
- Numeri di Fibonacci
f0 = 1, f1 = 1
fn = fn-1 + fn-2 per n >= 2

int fibonacci (int n)
{
int ris;
if(n == 0)
ris=1;
else if(n == 1)
ris = 1;
else
ris = fibonacci(n-1) + fibonacci(n-2);
return ris;
}

Domande da interrogazione

  1. Qual è il concetto principale della ricorsione?
  2. La ricorsione è un processo per risolvere un problema riducendolo in sottoproblemi che sono identici in struttura al problema originale ma più semplici da risolvere.

  3. Come si applica il principio di induzione nella dimostrazione di proposizioni?
  4. Il principio di induzione dimostra che una famiglia di proposizioni P(n) è vera per ogni n appartenente a N, partendo dalla base di induzione P(0) e utilizzando il passo induttivo per dimostrare che se P(n) è vero, allora anche P(n+1) è vero.

  5. Qual è la definizione ricorsiva del fattoriale di un numero naturale?
  6. La definizione ricorsiva del fattoriale è: 0! = 1 (base di induzione) e n! = n * (n-1)! (passo ricorsivo).

  7. Come funziona la ricorsione nella programmazione?
  8. Nella programmazione, una funzione è ricorsiva quando chiama se stessa direttamente o indirettamente, e utilizza una struttura di dati come lo STACK per gestire le chiamate e i valori intermedi.

  9. Qual è l'importanza del caso base nella ricorsione?
  10. Il caso base rappresenta un sottoproblema facilmente risolubile e serve come punto di riferimento per risolvere i casi più complessi, garantendo che la ricorsione termini correttamente.

Domande e risposte

Hai bisogno di aiuto?
Chiedi alla community