Algoritmi 1 Analisi e Programmazione • I Calcolatori Elettronici si differenziano da altri tipi di “macchine” per il fatto che possono essere “predisposti” alla risoluzione di problemi di diversa natura. • A tale scopo, è necessario “indicare” al Calcolatore quale è il problema che deve essere risolto. 2 Analisi e Programmazione • Per Analisi e Programmazione si intende l’insieme delle attività necessarie per la risoluzione dei problemi per mezzo di un Elaboratore, dalla formulazione del problema alla predisposizione dell’Elaboratore. Analisi e Programmazione Problema Risultati • Scopo dell’analisi è definire un Algoritmo: elenco finito di istruzioni necessarie per risolvere una classe di problemi; in generale non può essere eseguito da un elaboratore; • Scopo della programmazione è definire un Programma. Un programma è la descrizione comprensibile ed eseguibile di un algoritmo da parte di un elaboratore. 3 Algoritmi e Programmi Problema Analisi Algoritmo Programmazione Programma Risultati 4 Algoritmi • • • Il termine Algoritmo deriva dal nome di un matematico arabo al-Khuwarizmi (IX sec d.C.). Definizione formale: un Algoritmo è una successione ordinata di “istruzioni” (o passi) che definiscono le operazioni da eseguire su dei “dati” per risolvere una classe di problemi. Ogni problema corrisponde a dei dati sui quali l’Algoritmo opera e i risultati sono la soluzione a quel problema. 5 Algoritmi: un esempio • • • • Problema: Calcolo del Massimo Comune Divisore (M.C.D.) tra due numeri interi positivi a e b. Algoritmo di Euclide (300 a.c.): si basa sul fatto che ogni divisore comune ad a e b è anche divisore del resto r della divisione intera di a con b, se a > b ed r ≠ 0. Se r = 0, allora b è il M.C.D. richiesto. Quindi, dalla regola a × q + r = b con q ed r quoziente e resto della divisione, si ha: M.C.D.(a,b) = M.C.D.(b,r) se r ≠ 0, M.C.D.(a,b) = b se r = 0. 6 Algoritmo di Euclide per M.C.D(a,b) 1. 2. 3. 4. 5. 6. 7. inizio dell’algoritmo; acquisisci i valori di a e b dall’esterno; se b > a scambia tra loro i valori di a e b; calcola il resto r della divisione intera di a con b; se r = 0 allora comunica b all’esterno e vai al passo 7; se r ≠ 0 sostituisci il valore di a con il valore di b ed il valore di b con il valore di r e vai al passo 4; fine dell’algoritmo. 7 Algoritmi • • • Le istruzioni di un Algoritmo devono essere eseguite nello stesso ordine nel quale si presentano. Quindi il “flusso” va sempre in un’unica direzione, dalla prima all’ultima istruzione. Sono ammessi “salti” e “cicli” (vedi esempio Algoritmo M.C.D.). 8 Proprietà degli Algoritmi • Esistono dei precisi requisiti che devono essere soddisfatti affinché un elenco di istruzioni possa essere considerato un Algoritmo: 1. 2. 3. Finitezza: un Algoritmo deve essere finito, ossia ogni istruzione deve essere eseguita in un tempo finito e un numero finito di volte; Generalità: Ogni algoritmo deve fornire soluzione per tutti i problemi appartenenti ad una data classe, ed essere applicabile a tutti i dati appartenenti al suo insieme di definizione o dominio producendo risultati che appartengono al suo insieme di arrivo o codominio. Non ambiguità: devono essere definiti in modo univoco tutti i passi; devono essere evitati paradossi, contraddizioni ed ambiguità. In pratica significa che il significato delle istruzioni deve essere sempre lo stesso, indipendentemente dalla persona che esegue l’Algoritmo. 9 Proprietà degli Algoritmi • Consideriamo l’Algoritmo di Euclide per il M.C.D. e verifichiamo che effettivamente sia un Algoritmo: 1. E’ finito in quanto il resto r prima o poi diventa nullo, ponendo termine al processo di calcolo. 2. E’ generale in quanto permette di calcolare il M.C.D. di due qualunque numeri interi positivi. 3. E’ non ambiguo perché sono considerate tutte le situazioni possibili e per ogni situazione le azioni da compiere sono ben specificate. 10 Descrizione degli Algoritmi • • • Il linguaggio naturale non è adatto a descrivere gli algoritmi in quanto ambiguo e ridondante. E’ necessario adottare un linguaggio generalizzato costituito da strutture linguistiche prive di ambiguità e ridondanze; Le proposizioni presenti in un Algoritmo sono composte da due componenti fondamentali: 1. 2. Descrizione delle operazioni da eseguire (Istruzioni); Descrizione degli oggetti sui quali effettuare le operazioni (Dati). 11 Dati • • Costanti: mantengono lo stesso valore durante l’esecuzione dell’intero Algoritmo. Variabili: sono costituite da coppie <nome,valore>. 1. 2. 3. Il nome della variabile non cambia durante l’esecuzione e la identifica all’interno dell’algoritmo. Il valore deve appartenere ad un insieme detto insieme di definizione, che è l’insieme di tutti i possibili valori che la variabile può assumere. All’insieme di definizione sono associate delle regole di manipolazione per operare sui suoi elementi (es. le operazioni aritmetiche su interi positivi). 12 Dati: esempio M.C.D.(16,24) Istruzione a b r 2 16 24 Non definito 3 24 16 Non definito 4 24 16 8 6 16 8 8 4 16 8 0 13 Dati • Vettori: sono variabili contenenti insiemi di valori (detti elementi del vettore). – – – Tutti i valori devono appartenere allo stesso insieme di definizione. Il numero di elementi contenuti in un vettore è detto dimensione del vettore. Ogni elemento è indicato tramite un indice che ne identifica la posizione all’interno del vettore (es. V(1) è il primo elemento del vettore V, V(n) l’ultimo se n è la dimensione del vettore). 14 Dati • Matrici: sono generalizzazioni dei vettori ad un numero arbitrario di dimensioni. – – Nelle matrici a due dimensioni gli elementi vengono individuati tramite due indici, detti riga e colonna. Ad esempio M(3,4) indica l’elemento contenuto nella terza riga e nella quarta colonna della matrice M. 15 Istruzioni • Istruzione di assegnazione: imposta il valore corrente di una variabile. Si indica con nome di variabile ← espressione – espressione è una stringa di costanti, nomi di variabili ed operazioni. – nome di variabile indica la variabile il cui valore deve essere impostato al risultato di espressione. – I valori delle variabili contenute nell’espressione rimangono inalterati. – Esempi: a ← b, x ← a + 2. 16 Istruzioni: categorie principali 1. Istruzioni operative (Azioni): producono risultati se eseguite (es. istruzione di assegnazione); 2. Istruzioni di controllo: in funzione del verificarsi di condizioni determinano l’esecuzione di alcune istruzioni piuttosto che di altre; 3. Istruzioni di salto: alterano il normale ordine di esecuzione delle istruzioni; 4. Istruzioni di inizio e fine esecuzione; 5. Istruzioni di Input/Output: trasmissione dati o messaggi fra l’ambiente esterno e l’algoritmo. 17 Proposizioni e predicati • Come sono espresse le condizioni nelle istruzioni di controllo? – Le istruzioni di controllo verificano se una condizione è vera o falsa. – La condizione viene espressa per mezzo di predicati. • Proposizione: Costrutto del quale si può dire se è vero o falso. • Predicato: Una proposizione è un Predicato se in essa appaiono delle variabili e il valore di verità delle variabili determina il valore di verità della proposizione. I predicati si esprimono con operatori logici e relazionali. - Predicati Semplici: predicati di un solo operatore relazionale (>, <, M); - Predicati Composti: predicati con almeno un operatore logico (AND, OR, NOT). 18 Operatori Relazionali • • • • • • = ≠ > < ≥ ≤ uguale diverso maggiore minore maggiore o uguale minore o uguale 19 Operatori Logici e Tavole di Verità • Tavole di Verità: – descrivono i valori di verità dei predicati in funzione dei valori di verità delle singole parti. – Esprimono le modalità con cui operano gli operatori logici. • Esempi: A B A and B A B A or B A not A 0 0 0 0 0 0 0 1 0 1 0 0 1 1 1 0 1 0 0 1 0 1 1 1 1 1 1 1 20 Esempi di Predicati • • • • età > 30 (Predicato semplice) età ≥ 30 AD età ≤ 50 età > 30 OR età < 50 sempre vera! OT età > 50 21 Diagrammi a Blocchi • Linguaggio generalizzato per la descrizione di Algoritmi; • Un Diagramma a Blocchi (o Diagramma di Flusso) è la rappresentazione grafica di un Algoritmo. • Viene rappresentata la sequenza (il flusso) delle istruzioni in una forma elementare. 22 Diagrammi a Blocchi • Ad ogni tipo di istruzione (esclusi i “salti”) è associato un particolare simbolo grafico detto blocco elementare. • I blocchi sono collegati tra loro tramite frecce che indicano la “direzione del Flusso”. Inizio V Lettura Scrittura Azioni F Controllo Fine 23 Diagrammi a Blocchi • Un diagramma a blocchi è un insieme di blocchi costituito da: – un blocco iniziale, – un numero finito n ≥ 1 di blocchi azione e/o blocchi di lettura/scrittura, – un numero finito m ≥ 0 di blocchi di controllo, – un blocco finale. • Questo insieme di blocchi deve rispettare le cosiddette condizioni di validità. 24 Diagrammi a Blocchi: Condizioni di Validità • ciascun blocco azione o di lettura/scrittura ha una sola freccia entrante e una sola freccia uscente, • ciascun blocco di controllo ha una sola freccia entrante e due uscenti (Vero o Falso), • ciascuna freccia entra in un blocco o si innesta su un’altra freccia (ad esempio nei salti), • ogni blocco è raggiungibile dal blocco iniziale, • il blocco finale è raggiungibile da qualsiasi altro blocco. 25 Diagrammi a Blocchi: M.C.D(a,b) begin leggi a, b falso b>a r ← a mod b vero x←a a←b b←x b←r a←b falso r=0 vero scrivi b end 26 Diagrammi a Blocchi: M.C.D(a,b) • Osservazioni sul diagramma precedente: – L’operazione “scambiare i valori di a con b” è realizzata con l’ausilio di una variabile di appoggio x; questo è necessario in quanto l’assegnazione è un’operazione distruttiva: • La sequenza a ← b, b ← a, avrebbe cancellato il valore della variabile a, e conservato solo quello di b. – La funzione “mod” calcola il resto della divisione tra due numeri interi. 27 Analisi Strutturata • Procedimento che permette di ottenere descrizioni di algoritmi che siano facilmente documentabili e comprensibili; • Un diagramma a blocchi è strutturato se: – è costituito da un blocco iniziale, almeno un blocco di azione o lettura/scrittura ed un blocco finale, – è costituito da blocchi collegati tramite i seguenti schemi di flusso strutturati: • Schema di sequenza • Schema di selezione • Schema di iterazione 28 Schema di sequenza • Nota: il seguente schema è strutturato se e solo se sono strutturati gli schemi S1, S2, M, Sk begin S1 S2 SK end 29 Schema di selezione • Contiene un blocco di controllo che opera in uno dei seguenti modi: – Caso 1: subordina l’esecuzione di uno schema di flusso SV alla soddisfazione della condizione C. – Caso 2: permette di scegliere quale schema di flusso eseguire tra due schemi indicati SV ed SF. begin Nota: i seguenti schemi sono strutturati se e solo se sono strutturati gli schemi Sv e SF. falso C begin vero SV end falso C vero SV SF end 30 Schema di iterazione • Permette di eseguire più volte un determinato schema di flusso S. – Iterazione per vero: lo schema S viene eseguito finché una condizione C è vera. – Iterazione per falso: lo schema S viene eseguito finché una condizione C è falsa. Nota: i seguenti schemi sono strutturati se e solo se è strutturato lo schema S. begin begin S S C end vero falso C end 31 Schema di iterazione • Detto anche ciclo o loop, si distingue anche per la posizione della “condizione di fine ciclo”: – Controllo in Testa: la condizione viene verificata prima dell’esecuzione dell’Iterazione (che quindi può anche non essere eseguita). – Controllo in Coda: la condizione viene verificata dopo aver eseguito l’Iterazione (viene eseguita almeno una volta). Iterazione per vero con controllo in testa Inizializzazione Iterazione Condizione V Inizializzazione Condizione F Iterazione per falso con controllo in coda F V Iterazione 32 Schema di iterazione • Un ciclo è detto enumerativo (o definito) quando è noto a priori il numero di volte che deve essere eseguito. – Si usa la tecnica del contatore per controllarne l’esecuzione: si usa una variabile detta contatore del ciclo che viene incrementata (o decrementata) fino a raggiungere un valore prefissato. • Un ciclo è indefinito quando non è noto a priori il numero di volte che deve essere eseguito. – Questo accade quando la condizione di fine ciclo dipende dal valore di una o più variabili che o dipendono dall’interazione con l’esterno o vengono modificate all’interno dell’iterazione in modo complesso. 33 Diagrammi a blocchi: un altro esempio • Problema: Dato un vettore V contenente N numeri interi, calcolarne il valore massimo. • Algoritmo: scorrere il vettore V dal primo all’ultimo elemento (iterazione) e trovare il massimo (max): – Suppongo che max coincida con il primo elemento di V e lo confronto con il secondo elemento, se questo è maggiore di max aggiorno il valore di max. – Ogni elemento di V viene confrontato con max. 34 Diagrammi a blocchi: Max(V) con N = 100 falso 35 Algoritmi Ricorsivi • Un algoritmo si dice ricorsivo quando è definito in “termini di se stesso”; • E’ un approccio alternativo allo schema iterativo; • È costituito da due parti: 1. Passo base (stabilisce il risultato per valori precisi dei dati iniziali); 2. Passo di induzione (risultato per n in funzione del risultato per n-1). 36 Principio di Induzione • Un Algoritmo è definibile ricorsivamente se vale il Principio di Induzione: – Sia Pn una proposizione di cui si può dire se è vera o falsa, allora: Hp) Sia P0 vera; Supponendo Pn-1 vera, si dimostra che Pn è vera; Ts) Pn è vera ∀n. 37 Esempi di algoritmi ricorsivi • Potenza (definizione iterativa): a b = a1⋅ 42 a ⋅ ........ ⋅a 43 b volte • Potenza (definizione ricorsiva): b=0 1 a = b −1 a a b≠0 ⋅ b 38 Esempi di algoritmi ricorsivi • Fattoriale (definizione iterativa): n! = n ⋅ (n − 1) ⋅ ... ⋅ 1 • Fattoriale (definizione ricorsiva): n=0 1 n! = n ⋅ (n − 1)! n ≠ 0 39 Diagramma a blocchi del Fattoriale Iterativo Inizio i ←1 F fatt ← 1 i≤n V fatt ← fatt ⋅ i i ← i +1 Fine 40 Diagramma a blocchi del Fattoriale Ricorsivo Inizio V n=0 F fatt ← n ⋅ (n −1 )! fatt ← 1 Fine 41 Sviluppo del Fattoriale Ricorsivo 4! = 4 ⋅ 3! 4! = 4 ⋅ 3! = 4 ⋅ 6 = 24 3! = 3 ⋅ 2! 3! = 3 ⋅ 2! = 3 ⋅ 2 = 6 2! = 2 ⋅ 1! 2! = 2 ⋅ 1! = 2 ⋅ 1 = 2 1! = 1 ⋅ 0! Passo base 1! = 1 ⋅ 0! = 1 ⋅ 1 = 1 0! = 1 42 Algoritmi Metodo delle scomposizioni successive o approccio Top-Down • • • • Metodo di analisi utile nel caso di Algoritmi per problemi complessi. In pratica consiste nello scomporre il problema da risolvere in k sottoproblemi indipendenti, elaborando per ciascuno un possibile Algoritmo. Se il sottoproblema i-esimo, con i=1,..,k, risulta ancora troppo complesso, si procede ad una ulteriore scomposizione. Esempio generico: si pensi allo schema di Sequenza. 43 Complessità degli Algoritmi • Si definisce Complessità di un Algoritmo C(A) la funzione dei parametri rilevanti per A che determina il numero di operazioni necessarie per l’esecuzione di A. Quindi: C ( A) = f (n1 , n2 ,..., nk ) • Esempio: nel caso dell’Algoritmo per il calcolo del Massimo di un vettore, il solo e unico parametro rilevante è la dimensione N del vettore stesso: in tal caso si dirà che la complessità di A è proporzionale a f(N), e si indica: C ( A) = Ο( f ( )) 44