Vai alla Home Page About me Courseware Federica Living Library Federica Federica Podstudio Virtual Campus 3D Le Miniguide all'orientamento Gli eBook di Federica La Corte in Rete
 
 
Il Corso Le lezioni del Corso La Cattedra
 
Materiali di approfondimento Risorse Web Il Podcast di questa lezione

Ernesto Burattini » 8.Algoritmi di ricerca


Un caso di studio: il calcolo della radice quadrata

Il modo più semplice per calcolare la radice quadrata di un numero “a” è quello di utilizzare un algoritmo molto antico, usato dai babilonesi, e riproposto da Erone, che consiste nell’utilizzare la formula ricorrente

Xs= \frac{X_p+\frac{a}{X_p}}{2}

dove Xp è il valore precedente e Xs è quello successivo. Per poter applicare questa formula è necessario assegnare un valore iniziale a Xp; poiché Xp appare anche al denominatore poniamo come valore iniziale Xp=1.

Volendo calcolare la radice di 2, seguiamo i primi passi dell’algoritmo:
………………… Xp=1 .. → Xs=(1+2)/2=1,5
Poniamo ora Xp=1,5 → Xs=(1,5+2/1,5)/2=1,416
Poniamo ora Xp=1,416 e così via.

Un caso di studio: il calcolo della radice quadrata (segue)

L’algoritmo di Erone di Alessandria (vissuto tra il I° e II° sec. d.C.) utilizza solo le quattro operazioni dell’aritmetica.

L’algoritmo si sviluppa sulla base di alcune osservazioni geometriche.
Dato un numero A se costruiamo un quadrato di area A, il lato di questo quadrato sarà proprio la radice di A.

Per costruire questo quadrato eseguiamo una serie di approssimazioni successive partendo da un rettangolo i cui lati misurano h e A/h, con h minore di A. L’area del rettangolo è

h \cdot \frac Ah=A

cioè è uguale all’area del quadrato che cerchiamo. I lati sono invece uno minore e uno maggiore del lato del quadrato.

Il calcolo della radice quadrata

Calcoliamo ora la media aritmetica delle misure dei due lati del rettangolo h_1=\frac{h+\frac Ah }{2} , avremo ovviamente che h1 è maggiore di h.

Costruiamo un nuovo rettangolo i cui lati misurano h1\frac {A}{h_1}.


Il calcolo della radice quadrata (segue)

Avremo ancora che l’area del rettangolo, pari a h_1 \cdot \frac{A}{h_1}=A resta uguale a quella del quadrato, mentre h1 è un valore approssimato per eccesso del lato del quadrato, mentre \frac {A}{h_1} è un valore approssimato per difetto. La media aritmetica così ottenuta fornisce ora un valore h1 più vicino a \sqrt A di quanto lo fosse h.

Calcolando di nuovo la media aritmetica delle misure dei due lati del rettangolo, otteniamo h_2=\frac{h_1+\frac {A}{h_1}}{2} dove ancora h2 è maggiore di h1 ma sempre minore di A.

Il calcolo della radice quadrata (segue)

Reiteriamo il processo costruendo un rettangolo i cui lati misurano h2 e \frac {A}{h_2} . Avremo un valore approssimato per eccesso del lato del quadrato e un valore approssimato per difetto. Il valore di h2 è però più vicino a A di quanto lo fosse h1.

Proseguendo per questa strada, cioè con successive approssimazioni, costruiamo due successioni di numeri che approssimano, una per eccesso e una per difetto, la radice quadrata di A.

Quadrato da costruire


Algoritmo di Erone

Nella prossima diapositiva si mostra l’algoritmo di Erone mediante un algoritmo iterativo.

Viene richiesto il valore dell’approssimazione che si vuole ottenere per il calcolo della radice quadrata (ε) e quindi iterativamente, tramite un ciclo si esegue l’algoritmo fin quando l’approssimazione ottenuta non è minore di ε.

Algoritmo di Erone – codice iterativo

#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;
// Calcola radice quadrata
main () {
const float eps=0.000001;
float a,x ;
// precondizioni: a>=0 and eps>0
cout << " Calcolo della radice di a:  a=";
cin >> a;
x=1.0;
while (fabs(x-a/x)/2>=eps)
x=(x+a/x)/2;
//Postcondizioni: x>0   |x-a/x|<eps
cout <<"Radice di "<< a <<"="<< x <<endl;
system("pause");
}

Algoritmo di Erone (segue)

L’algoritmo di Erone si presta perfettamente ad una sua interpretazione in chiave ricorsiva.

Il caso base è rappresentato dal raggiungimento del valore di approssimazione ε richiesta, mentre la chiamata ricorsiva riproduce la formula di Erone.

La Radice Quadrata con il metodo di Erone

Mostra codice

Allegato: radice quadrata.

Algoritmi di ricerca lineare

Problema: Cercare tra i valori contenuti in un Array un preassegnato valore.
Esempio: Data una lista di N numeri verificare se esiste un preassegnato valore.

Un algoritmo ricorsivo, che risolva questa problema presenta due casi base:

  • la ricerca è finita se nessun elemento uguale a quello cercato esiste;
  • la ricerca è finita se almeno un elemento uguale a quello cercato è stato trovato.

Supponiamo di partire dall’ultimo elemento della lista e risalire fino in cima nella ricerca dell’elemento.

Algoritmi di ricerca lineare (segue)

Soluzione iterativa:

Gestire opportunamente l’indice dell’array in cui sono contenuti gli elementi su cui fare la ricerca.

I criteri per stabilire il nuovo valore da attribuire all’indice possono essere i più diversi.

E’ però importante che una volta stabilito che un elemento individuato da un certo indice non è quello cercato questo elemento non venga più esaminato. Di seguito si mostra una versione iterativa.

Si noti che poiché ad ogni passo della ricerca eliminiamo un elemento il massimo numero di passi che potranno essere eseguiti è pari al numero di elementi.

Algoritmi di ricerca: soluzione iterativa

Mostra codice

Algoritmi di ricerca: soluzione iterativa (segue)


Caratteristiche di una ricerca ricorsiva

Una chiamata ricorsiva implica sempre una riduzione del sub range di possibili candidati. Quindi nell’intestazione è presente almeno un parametro che rappresenta il subrange di elementi. Il valore del parametro in ogni istante di computazione è funzione di un qualche subrange candidato locale. Questa espressione, i cui valori devono rappresentare una riduzione del subrange candidato, viene calcolata e al successivo processo di ricerca i valori ottenuti vengono applicati.

Caratteristiche di una ricerca ricorsiva (segue)

La condizione di terminazione è espressa in termini dei parametri del subrange candidato. Questa condizione rappresenta il caso base quando non restano altri subrange candidati alla ricerca.

L’altro caso base si ha quando la ricerca ha buon esito, quando cioè a[Candidato] coincide con Chiave.

Ricerca binaria

Assegnato un vettore ordinato A di interi, di dimensione N, determinare la posizione di un elemento mediante una ricerca binaria.
Ricordiamo che la ricerca binaria si basa sulla tecnica del divide et impera.

Dividiamo gli elementi in due parti; essendo tutti gli elementi ordinati, confrontiamo l’elemento cercato x con il valore M che separa le due parti: se x<M allora dobbiamo continuare a cercare nella prima parte, altrimenti cercheremo nella seconda parte.

Dividiamo la parte scelta ancora in due e applichiamo sempre il ragionamento precedente. L’algoritmo termina o quando l’ultimo elemento rimasto dalle successive suddivisioni è uguale a quello cercato, oppure quando l’intervallo rimasto non è più suddivisibile il che implica che il nostro elemento non appartiene al vettore.

Ricerca binaria (segue)

Un algoritmo iterativo per la ricerca binaria è il seguente: Mostra codice

Si noti che la variabile i, inizialmente posta =-1, cambia solo se troviamo il dato cercato, quindi se in uscita, la funzione ritorna -1, implica che il dato cercato non è stato trovato.

Ricerca binaria ricorsiva

Scriviamo la funzione tenendo presente che vet[] è il vettore di interi, x è l’elemento da cercare, basso rappresenta l’indice minimo, alto quello massimo del vettore di interi.
Mostra codice

Ricerca binaria ricorsiva (segue)

Il codice è pertanto il seguente: Mostra codice

Esercizio

Scrivere una funzione ricorsiva che ritorna vero se gli elementi di unArray di interi, con valori assegnati nel subrange 1…TotElem, sono in ordine crescente.

Obiettivo: ricercare un elemento che sia fuori ordine in un dato subrange.

Ridurre di volta in volta il subrange fino a quando in questo resta un solo elemento allora vuol dire che la ricerca è finita e la risposta è TRUE.

Se invece si verifica che è vera l’espressione

UnArray[N-1]>UnArray[N]

questo significa che è stato trovato un elemento non in ordine e la funzione ritorna FALSE.

Esercizio

Con una function ricorsiva, utilizzando la tecnica dell’INSERTION SORT, inserire in maniera ordinata, in un array di numeri interi, i valori letti da tastiera fin quando non si introduce lo 0.

Mostra codice

Allegato: Mostra codice

N.B. il codice allegato prevede l'uso del file header InsertArray.h introdotto nella lezione 7 slide 12.

I materiali di supporto della lezione

Insertion

Radice quadrata

  • Contenuti protetti da Creative Commons
  • Feed RSS
  • Condividi su FriendFeed
  • Condividi su Facebook
  • Segnala su Twitter
  • Condividi su LinkedIn
Progetto "Campus Virtuale" dell'Università degli Studi di Napoli Federico II, realizzato con il cofinanziamento dell'Unione europea. Asse V - Società dell'informazione - Obiettivo Operativo 5.1 e-Government ed e-Inclusion