Logo dell'Università di Catania: Siciliae Studium Generale 1434 Logo del Centro IPPARI, Programmazione
matite e gomma
Loghi istituzionali: Siciliae Studium Generale 1434, Centro ricerche IPPARI, Università di Catania, Facoltà di Scienze Matematiche, Fisiche, Naturali, Insegnamento di Programmazione

Algoritmi ricorsivi

Lezione 20 di Programmazione 2

Docente: Giuseppe Scollo

Università di Catania, sede di Comiso (RG)
Facoltà di Scienze Matematiche, Fisiche e Naturali
Corso di Studi in Informatica applicata, AA 2007-8

Logo di Conformità WCAG-1 di Livello Tripla A, W3C-WAI Web Content Accessibility Guidelines 1.0 Validazione XHTML 1.0 Validazione CSS 2

Indice

  1. Algoritmi ricorsivi
  2. primi esempi
  3. ricorsione o iterazione?
  4. valutazione di espressioni prefisse
  5. funzioni ricorsive per liste concatenate
  6. algoritmi divide et impera
  7. esempio: ricerca del massimo
  8. problema delle torri di Hanoi
  9. esercizi

primi esempi

definizione ricorsiva di una funzione per il calcolo del fattoriale:

definizione ricorsiva, ma non induttiva, di una funzione per il problema di Collatz:

per la definizione precedente, definiamo una funzione che ne misuri la profondità della ricorsione:

algoritmo di Euclide per il calcolo del massimo comun divisore di due numeri:

ricorsione o iterazione?

è sempre possibile trasformare una definizione ricorsiva di funzione in una equivalente non ricorsiva, usando opportunamente l'iterazione (v. esercizi)

viceversa, è sempre possibile trasformare una definizione di funzione che abbia cicli in una equivalente ricorsiva priva di cicli

abbiamo dunque due stili di programmazione: quale preferire?

valutazione di espressioni prefisse

la definizione ricorsiva della funzione di valutazione fornisce un esempio di analisi sintattica (ingl. parsing) per discesa ricorsiva

il primo parametro della funzione è un puntatore all'intera espressione da valutare; il secondo parametro, passato per riferimento, è l'indice alla posizione iniziale della sua sottostringa da valutare in ciascuna invocazione ricorsiva

funzioni ricorsive per liste concatenate

si ha ricorsione in coda (ingl. tail recursion) quando un'invocazione ricorsiva è presente nell'ultima istruzione di una definizione ricorsiva di funzione

tre delle seguenti definizioni sono ricorsive in coda, mentre non lo è la definizione di traverseR, per l'attraversamento in ordine inverso di una lista concatenata

algoritmi divide et impera

si è già invocata la regola divide et impera, per caratterizzare una vasta classe di algoritmi, quando si sono introdotte le relazioni di ricorrenza

appare ora chiaro che gli algoritmi di questa classe hanno definizioni ricorsive basate sull'induzione

per questi algoritmi, la struttura ricorsiva del programma fornisce lo schema essenziale

riguardo al secondo aspetto, si dimostrano spesso per induzione proprietà di sottoclassi di algoritmi divide et impera

eccone una, a titolo di esempio:

esempio: ricerca del massimo

l'approccio divide et impera fornisce spesso una soluzione rapida al problema, in termini di tempo necessario a trovarla e/o codificarla

ecco ad esempio una soluzione divide et impera al problema di trovare il massimo in un insieme di elementi

per il risultato enunciato in precedenza, questo algoritmo ha profondità di ricorsione inferiore al numero N di elementi nell'array

l'analisi dell'algoritmo permette una valutazione più accurata della profondità di ricorsione, che è all'incirca lg N

problema delle torri di Hanoi

dati: 3 pioli e N dischi, tutti di diverso diametro, inizialmente posti tutti in un piolo, per diametri decrescenti dalla base alla sommità

problema: trasferire la pila di dischi su un altro piolo, spostando solo un disco alla volta e senza mai porre un disco su un altro di diametro minore

soluzione ricorsiva: (il segno di) d rappresenta la direzione circolare dello spostamento, la sequenza di invocazioni a muovi generata dall'algoritmo rappresenta la soluzione

profondità della ricorsione: N, numero totale di invocazioni ricorsive: 2N-1

esercizi

  1. dare definizioni non ricorsive delle funzioni collatz e gcd equivalenti alle rispettive definizioni ricorsive qui proposte
  2. v. esercizio 5.1 del testo (Sedgewick, 2003), a p. 208: dare una definizione ricorsiva della funzione lg(N!) che riesca a produrre il risultato anche per valori di N abbastanza grandi da rendere N! non rappresentabile
  3. v. esercizio 5.2 del testo (Sedgewick, 2003), a p. 208: dare una definizione ricorsiva della funzione N! mod M che produca il risultato per qualsiasi valore rappresentabile di N, dunque anche per valori abbastanza grandi da rendere N! non rappresentabile
  4. la Proprietà 5.1 nel testo (Sedgewick, 2003), a p. 212, recita: una funzione ricorsiva che divide un problema di dimensione N in due parti indipendenti (non vuote) che risolve in modo ricorsivo, invoca se stessa per meno di N volte; verificare che tale formulazione è erronea
    • la dimostrazione per induzione fornita dal testo è basata sulla seguente ricorrenza, dove TN è il numero totale di chiamate ricorsive su un input di dimensione N, e si ipotizza che le due parti abbiano rispettivamente dimensione k e N-k: trovare in questa ricorrenza la fonte dell'errore nel testo
      • TN = Tk + TN-k + 1, per N > 1, dove T1 = 0