La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Che cosa e' un algoritmo e come vogliamo studiare gli algoritmi?

Presentazioni simili


Presentazione sul tema: "Che cosa e' un algoritmo e come vogliamo studiare gli algoritmi?"— Transcript della presentazione:

1 Che cosa e' un algoritmo e come vogliamo studiare gli algoritmi?
Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Che cosa e' un algoritmo e come vogliamo studiare gli algoritmi? Vedi: D.E. Knuth, The art of computer programming, Vol. 1, Fundamental Algorithms, Addison-Wesley, cap. 1, Basic concepts E. Horowitz, S. Sahni, Computer algorithms, Computer Science Press, cap. 1, Introduction Copyright © by Claudio Salati. Lez. 1

2 ALGORITMO (o algorismo)
Il nuovissimo Melzi, 1950 Aritmetica col sistema arabo (dal matematico arabo Al-Kuarismi, del IX secolo) Processo del calcolo Grande Dizionario Enciclopedico UTET, 1954 Qualunque procedimento di calcolo Questa strana parola nasce dal nome del matematico arabo Al Khovarizmi … passo' ad indicare le regole di calcolo Cosi' si dice anche oggi Algoritmo di Euclide per indicare il procedimento di calcolo che serve per la ricerca del massimo comun divisore The Concise Oxford Dictionary, 1976 Arabic (decimal) notation of numbers Process or rules for (esp. machine) calculation

3 ALGORITMO: aritmetica col sistema arabo
Sistema arabo-indiano: basato sulla notazione posizionale e su cifre relative ad una base, e.g. in base 10: nm nm n1 n0 = nm*10m+ nm-1*10m n1*101+ n0*100 Le operazioni su numeri qualsiasi si basano sulla capacita’ di operare sulle singole cifre Algoritmo di addizione typedef digit[MAXDIGIT] numero; // numero rappresentato come sequenza di MAXDIGIT digit, // il digit 10k in posizione k nella sequenza void addizione(numero op1, numero op2, numero somma) { unsigned riporto = 0, pot, parziale; for (pot = 0; pot < MAXDIGIT; pot += 1) { parziale = op1[pot] + op2[pot] + riporto; riporto = parziale / 10; parziale = parziale % 10; digit[pot] = parziale; } assert(riporto==0); // altrimenti overflow

4 Algoritmo Microsoft® Encarta® Enciclopedia
Algoritmo Microsoft® Encarta® Enciclopedia. © Microsoft Corporation. Tutti i diritti riservati. Termine che formalizza il concetto intuitivo di procedura generale, di metodo sistematico valido per risolvere una certa classe di problemi. In matematica, è la soluzione di un problema basata sull'uso ripetuto di un semplice metodo computazionale (ne è un esempio comune il procedimento dell'operazione di divisione in aritmetica - in realta' il procedimento di tutte le 4 operazioni nell’aritmetica basata sui numeri arabi, quella in notazione posizionale). In informatica, indica, in generale, una sequenza di passi successivi, ciascuno dei quali specifica un'azione (o istruzione) eseguibile in modo meccanico. La sequenza completa permette di risolvere un problema, una volta che siano assegnate le condizioni iniziali. In informatica, la nozione di algoritmo contiene due concetti impliciti, fondamentali ai fini dell'esecuzione dell'algoritmo stesso: quello di automa, l'esecutore meccanico dell'algoritmo, e quello di linguaggio in cui l'algoritmo è scritto, che l'automa riconosce.

5 Algoritmo Microsoft® Encarta® Enciclopedia
Algoritmo Microsoft® Encarta® Enciclopedia. © Microsoft Corporation. Tutti i diritti riservati. L'algoritmo deve rispettare alcune proprietà fondamentali: effettività, vale a dire deve essere effettivamente eseguibile da un automa (o, in linguaggio dei computer, deve essere programmabile); finitezza di espressione (statica), ovvero il numero di istruzioni da eseguire deve essere finito; finitezza della procedura (dinamica), ovvero deve essere possibile concludere il calcolo, per qualsiasi situazione dei dati iniziali; determinismo, ovvero a ogni passo della procedura deve essere definita una e una sola operazione da eseguire. L'algoritmo può essere scritto con espressioni logiche o termini matematici, o in forma lessicale.

6 ALGORITMO (in informatica!)
Definizione 1 UN METODO PRECISO UTILIZZABILE DA UN CALCOLATORE PER LA SOLUZIONE DI UN PROBLEMA Definizione 2 DESCRIZIONE DI UNA SEQUENZA ORDINATA E FINITA (staticamente e dinamicamente) DI AZIONI BEN DEFINITE ED EFFICACI CHE A PARTIRE DA UN INSIEME I DI DATI DI INGRESSO CHE SODDISFANO ALL'INSIEME DI CONDIZIONI P PRODUCE UN INSIEME O DI VALORI DI USCITA CHE GODONO DELL'INSIEME DI PROPRIETA' C

7 ALGORITMO: PAROLE CHIAVE 1
TEMPO FINITO: IL VINCOLO REALE E' MOLTO PIU' STRINGENTE: ABBASTANZA PICCOLO! EFFICIENZA DEGLI ALGORITMI AZIONI BEN DEFINITE: e.g.: COSA SIGNIFICA -8 DIV -5? CI SONO ALMENO 2 DEFINIZIONI DIVERSE: -8 : -5 = +2 oppure -8 : -5 = +1 AZIONI EFFICACI: consideriamo una azione efficace quando e' eseguibile in tempo finito da un calcolatore. quando ci riferiamo ad un calcolatore ci riferiamo a qualcosa di simile a quello che teniamo sulla scrivania e usiamo solitamente NON SI PUO' MOLTIPLICARE O DIVIDERE O PER , ma solo per una sua approssimazione finita

8 ALGORITMO: PAROLE CHIAVE 2
} problema ben definito INPUT: I, P(I) OUTPUT: O, C(O) SEQUENZA ORDINATA: STIAMO ASSUMENDO UN PARTICOLARE MODELLO COMPUTAZIONALE, IL MODELLO DI VON NEUMANN DESCRIZIONE: e' un testo che descrive staticamente (tramite istruzioni) una successione di azioni da eseguire dinamicamente La distinzione statico vs. dinamico e' fondamentale. Noi ragioneremo sul testo statico e non sul/i processo/i dinamico/i che lo interpreta/no. Un processo dinamico e' condizionato dagli specifici dati in ingresso, il testo statico no (se non per le proprieta' generali P(I)).

9 PROBLEMA Template: TROVARE UN ALGORITMO
CHE A PARTIRE DA UN INSIEME I DI DATI DI INGRESSO CHE SODDISFANO ALL'INSIEME DI CONDIZIONI P PRODUCA UN INSIEME O DI RISULTATI DI USCITA CHE GODONO DELL'INSIEME DI PROPRIETA' C Ogni problema che affrontiamo deve, in linea di principio, poter essere espresso secondo la formula indicata dal template MINIMA VULGARIA: SE NON C'E' UN PROBLEMA (FORMULABILE CHIARAMENTE) NON PUO' ESISTERE L'ALGORITMO CHE LO RISOLVE.

10 Citazioni Ludwig Wittgenstein, Tractatus logico-philosophicus, Einaudi
6.2.4 Il metodo della matematica per pervenire alle sue equazioni e’ il metodo di sostituzione. Infatti le equazioni esprimono la sostituibilita’ di due espressioni, e noi procediamo da un certo numero di equazioni a nuove equazioni sostituendo espressioni con altre, corrispondentemente alle equazioni. 6.5 Di una risposta che non si puo’ formulare non puo’ formularsi neppure la domanda. L’enigma non v’e’. Se una domanda puo’ porsi, puo’ pure aver risposta. (warning: Goedel: "purtroppo Wittgenstein si e' sbagliato") ? Cio’ che si puo’ dire, lo si puo’ dire chiaramente (citazione approssimata). 7 Su cio’ di cui non si puo’ parlare, si deve tacere.

11 Modello computazionale di Von Neumann - 1
E’ il modello computazionale dei processori hardware tradizionali: stato del programma o dati vs. azioni o istruzioni, ciascuna delle quali istruzioni modifica lo stato del programma e/o determina quale e' la prossima istruzione del programma da eseguire lo stato del programma e' rappresentato dal contenuto delle celle di memoria (memoria centrale del calcolatore = array di celle ad accesso diretto o random) e dei registri del processore dall'indirizzo della prossima istruzione da eseguire di norma la prossima istruzione da eseguire e' quella che segue quella correntemente in esecuzione nel testo del programma (sequenza dinamica = sequenza statica), salvo che l'istruzione in esecuzione non trasferisca esplicitamente il controllo ad un'istruzione diversa

12 Modello di Von Neumann o imperativo - 2
anche il programma e' memorizzato nella memoria del calcolatore (ma di norma non e' modificabile durante l'esecuzione) nei linguaggi di programmazione imperativi si adotta sostanzialmente lo stesso modello: stato del programma  variabili istruzione fondamentale  assegnamento istruzioni di controllo di flusso

13 ALGORITMO DI EUCLIDE 1a // PER IL CALCOLO DEL MCD DI DUE NUMERI
// NATURALI > 0 // I = {i1, i2} // P = {ikN, ik>0 : k{1, 2}} // O = {gcd}, // C = {gcdN, gcd=MCD(i1, i2)} unsigned euclide_1 (unsigned i1, unsigned i2) { unsigned r, gcd; unsigned k1 = i1; unsigned k2 = i2;

14 ALGORITMO DI EUCLIDE 1b assert((i1>0) && (i2>0));
assert((k1>0) && (k2>0)); if (k2>k1) { r = k1; k1 = k2; k2 = r; } 06 assert((k1>=k2) && (k2>0)); r = k1 % k2; while (r!=0) { k1 = k2; k2 = r; r = k1 % k2; } gcd = k2; return(gcd); }

15 ALGORITMO DI EUCLIDE 1c Stiamo considerando una successione di triple:
k1<1> k2<1> r<1> k1<2> k2<2> r<2> k1<3> k2<3> r<3> . . . k1<m> k2<m> r<m> in cui (definizione ricorsiva): k1<1> = i1, k1<j+1> = k2<j> k2<1> = i2, k2<j+1> = r<j> r<j> = k1<j> % k2<j> Quando: r<j> = 0 noi affermiamo che: MCD(i1, i2) = k2<j> N.B.: se nm0 e n%m=0 e' evidente che MCD(n, m) = m m e' un divisore di n m e' un divisore, il massimo divisore, di se stesso Quello che stiamo asserendo e' che, per qualunque valore di j, MCD(i1,i2) = MCD(k1<1>,k2<1>) = MCD(k1<j>,k2<j>)

16 Parentesi assert((i1>0) && (i2>0)); assert(i1>0 && i2>0);
N.B.: Durante tutto il corso si usera' l'espressione numero naturale per indicare un numero intero non negativo Abbiamo scritto assert((i1>0) && (i2>0)); anziche' assert(i1>0 && i2>0); Perche'? Le due espressioni hanno lo stesso significato? Quale e' il significato di una istruzione/espressione? Chi ci assicura che euclide_1() fa davvero quello che promette di fare? In particolare: chi ci assicura che il ciclo while termina?

17 ALGORITMO DI EUCLIDE 2a // PER IL CALCOLO DEL MCD DI DUE NUMERI
// NATURALI  0 // I = {i1, i2} // P = {ikN, ik0 : k{1, 2}} // O = {return}, // C = {return N, // return = (i1!=0 && i2!=0) ? // MCD(i1, i2) // : MAX(i1, i2)} unsigned euclide_2 (unsigned i1, unsigned i2) { assert((i1>=0) && (i2>=0));

18 ALGORITMO DI EUCLIDE 2b unsigned new_i1; 03 if (i2 > i1) { 04
new_i1 = i2; i2 = i1; i1 = new_i1; } assert((i1 >= i2) && (i2 >= 0)); while (i2!=0) { new_i1 = i2; i2 = i1 % i2; i1 = new_i1; } return(i1); }

19 ALGORITMO DI EUCLIDE 2c In realta' il primo elemento di ciascuna delle triple considerate nell'algoritmo euclide_1() non viene mai utilizzato (dopo che si e’ effettuato il calcolo del terzo elemento della tripla) ne' per verificare se l'algoritmo e' terminato (viene utilizzato il terzo elemento) ne' per determinare gli elementi della prossima tripla (vengono utilizzati il secondo ed il terzo elemento) (il primo elemento di una tripla e’ utilizzato solo per il calcolo del terzo elemento della tripla stessa) Possiamo quindi "eliminare" il primo elemento di ciascuna tripla, limitandoci a considerare la coppia formata dagli ultimi due elementi. E' quello che fa l'algoritmo euclide_2()

20 Note e confronti P_1(I)  P_2(I) C_1(O)  C_2(O)
assert() e' importata dallo header file standard assert.h se l'espressione tra parentesi e' vera non succede niente, ma se e' falsa l'esecuzione del programma viene interrotta notare che in euclide_2() l'asserzione assert((i1>=0) && (i2>=0)); e' banalmente vera: i1 e i2 sono di tipo unsigned! L'utilizzo del type-system del linguaggio di programmazione ci consente di esprimere le caratteristiche del problema Le due funzioni euclide_1() ed euclide_2() sono molto diverse tra loro: P_1(I)  P_2(I) C_1(O)  C_2(O)

21 ALGORITMO DI EUCLIDE 3a // PER IL CALCOLO DEL MCD DI DUE NUMERI
// NATURALI > 0 // I = {i1, i2} // P = {ikN, ik>0 : k{1, 2}} // O = {gcd}, // C = {gcdN, gcd=MCD(i1, i2)} unsigned euclide_3 (unsigned i1, unsigned i2) { unsigned newk1; unsigned gcd; unsigned k1 = i1; unsigned k2 = i2;

22 ALGORITMO DI EUCLIDE 3b assert((i1>0) && (i2>0));
assert((k1>0) && (k2>0)); // se k2>k1 la prima iterazione effettua // lo scambio: questa azione e' evidente? while (k2!=0) { newk1 = k2; k2 = k1 % k2; k1 = newk1; } gcd = k1; return(gcd); }

23 ALGORITMO DI EUCLIDE 3c Infatti se k2 > k1 e': k1 / k2 = 0
k1 % k2 = k1 per cui durante la prima iterazione newk1 assume il valore di k2<0> k2<1> assume il valore di k1<0> k1<1> assume il valore di newk1, cioe' di k2<0>

24 ALGORITMO DI EUCLIDE: versione ricorsiva
// PER IL CALCOLO DEL MCD DI DUE NUMERI // NATURALI  0 // I = {i1, i2} // P = {k{1, 2}: ikN, i1i20} // O = {gcd}, // C = {gcdN, // gcd = (i1!=0 && i2!=0) ? MCD(i1, i2) // : i1} unsigned mcd (unsigned i1, unsigned i2) { assert((i1>=i2) && (i2>=0)); return (i2==0 ? i1 : mcd(i2, i1 % i2)); 03 }

25 PROGRAMMA IF (N<>0) AND ((M DIV N) > K) THEN …
E' UN ALGORITMO FORMULATO IN UN PARTICOLARE LINGUAGGIO DI PROGRAMMAZIONE IL LINGUAGGIO DEVE ESISTERE: DEVONO ESISTERE INTERPRETI E/O COMPILATORI, E LA SUA SEMANTICA DEVE ESSERE BEN DEFINITA e.g. differenza (anche per la precedenza degli operatori!) tra lo statement Pascal IF (N<>0) AND ((M DIV N) > K) THEN … (semantica di valutazione dell'operatore AND per valore e quindi statement errato) lo statement C if (N!=0 && M/N>K) … ; (semantica di valutazione dell'operatore && per nome, o short-circuit, e quindi statement corretto)

26 CORRETTEZZA DELL'ALGORITMO DI EUCLIDE
Assumiamo (w.l.g.) i1  i2 > 0 allora si puo' scrivere (qN, rN ): i1 = q * i2 + r UN QUALSIASI NUMERO j CHE DIVIDE SIA i1 CHE i2 DEVE DIVIDERE ANCHE r, ED E' VERO ANCHE CHE QUALSIASI DIVISORE COMUNE DI i2 E r DEVE DIVIDERE ANCHE i1 CIO' E' VERO IN PARTICOLARE PER IL MCD DI i1 E i2 PERCIO' (indicando con r il resto della divisione di i1 per i2) SE r=0 ALLORA MCD(i1, i2) = i2 ( UN NUMERO NON PUO' ESSERE DIVISO DA NUMERI PIU' GRANDI DI LUI ) SE r0 ALLORA LA RICERCA DI MCD(i1, i2) E' RICONDOTTA ALLA RICERCA DI MCD(i2, i1 % i2) (ESSENDO MCD(i1, i2) = MCD(i2, i1 % i2))

27 CORRETTEZZA DELL'ALGORITMO DI EUCLIDE
In realta' quello che abbiamo dimostrato e' la validita' della logica dell'algoritmo Non abbiamo nemmeno fatto riferimento ad una versione precisa dell'algoritmo/programma, tra le 4 che abbiamo considerato! In effetti non ci siamo riferiti a nessuna descrizione precisa dell'algoritmo N.B.: scrivere un programma e' una maniera di descrivere in modo preciso un algoritmo. Ci consente di parlarne in modo preciso (perche’, per definizione, il significato di ogni statement del programma deve essere chiaro e univoco). Quello che vorremmo e': potere verificare la validita' logica degli algoritmi che utilizziamo, potere verificare la correttezza dei programmi che scriviamo.

28 TERMINAZIONE DELL'ALGORITMO DI EUCLIDE
Assumiamo i1  i2 > 0 allora si puo' scrivere: i1 = q * i2 + r dove q = i1 / i2 e i2 > r  0 PERCIO': SE r=0 L'ALGORITMO TERMINA IMMEDIATAMENTE e questo e' in particolare il caso quando i1=i2 SE r0 (e quindi i1>i2) ALLORA i1 E i2 DECRESCONO STRETTAMENTE DA UNA ITERAZIONE ALL'ALTRA ED ESSENDO 1  MCD(i1, i2) LA PROCEDURA DEVE TERMINARE IN AL MASSIMO i2 ITERAZIONI

29 COMPLESSITA' DELL'ALGORITMO DI EUCLIDE
SI E' DETTO CHE L'ALGORITMO TERMINA AL MASSIMO IN i2 PASSI: SI RIESCE A DARE UN LIMITE PIU' STRINGENTE? CONSIDERIAMO: i1 > i2 > 0, i1 = q * i2 + r dove q = i1 / i2 e i2 > r  0 SE i2  (i1 / 2) ALLORA IN UNA ITERAZIONE i1 SI DIMEZZA (ALMENO) SE i2  (i1 / 2) ALLORA E' r < (i1 / 2) ED IN AL PIU' 2 ITERAZIONI i1 SI DIMEZZA PERCIO' L'ALGORITMO E' DI COMPLESSITA' LOGARITMICA: L'ITERAZIONE NON VIENE ESEGUITA PIU' DI 2*log2i1 VOLTE NON ABBIAMO CERCATO UN RISULTATO ESATTO, MA UN ORDINE DI COMPLESSITA'. QUESTO DIPENDE DALL'ALGORITMO, LE COSTANTI MOLTIPLICATIVE, ADDITIVE, ... ANCHE DAL PROGRAMMA

30 CONFRONTO TRA LE DIVERSE VERSIONI DELL'ALGORITMO DI EUCLIDE
DOMINIO DI DEFINIZIONE DELL'ALGORITMO, e.g.: NUMERI INTERI NON NEGATIVI vs. NUMERI INTERI POSITIVI VINCOLO (pre-condizione) i1  i2 EFFICIENZA/TEMPO DI ESECUZIONE Nell'esempio i quattro programmi condividono l'algoritmo, per cui l'efficienza e’ dello stesso ordine. Pero’, ci sono differenze? Come si confronta la versione ricorsiva? LUNGHEZZA DEL TESTO DEL PROGRAMMA CHIAREZZA Utilizzo del linguaggio per esprimere caratteristiche del problema Scambio implicito di i1 e i2 quando i2 > i1 in euclide_3() ELEGANZA (e.g. trattamento dei casi particolari) DOCUMENTAZIONE, ORGANIZZAZIONE

31 STUDIO DEGLI ALGORITMI 1
COME INVENTARE ALGORITMI: STRATEGIE DI PROGETTO DIVIDE-AND-CONQUER, GREEDY METHOD, ALGORITMI PROBABILISTICI, ... COME DIMOSTRARE CHE NON ESISTONO ALGORITMI EFFICIENTI O CHE UN PROBLEMA E' TROPPO DIFFICILE { CHI LO RISOLVESSE VINCEREBBE IL PREMIO NOBEL PER L'INFORMATICA, ISTITUITO APPOSITAMENTE } E, PIU' IN GENERALE, COME VALUTARE LA COMPLESSITA' DI UN PROBLEMA COME ESPRIMERE ALGORITMI, cioe` COME SCRIVERE PROGRAMMI PROGRAMMAZIONE STRUTTURATA PROGETTAZIONE TOP-DOWN PROGETTAZIONE PER RAFFINAMENTI SUCCESSIVI

32 STUDIO DEGLI ALGORITMI 2
COME VERIFICARE LA CORRETTEZZA LA TERMINAZIONE DI UN ALGORITMO O PROGRAMMA COME ANALIZZARE LA EFFICIENZA/COMPLESSITA' NELLO SPAZIO (e.g. STRUTTURE DATI IN MEMORIA) NEL TEMPO (DI ESECUZIONE) DI UN PROGRAMMA COME OPERARE DEBUGGING TESTING PROFILING (caratterizzazione) DI UN PROGRAMMA. (N.B. NON SEMPRE L'ALGORITMO TEORICAMENTE OTTIMALE E' IL MIGLIORE DA USARE PRATICAMENTE, e.g. Quicksort, algoritmo di Dantzig per la Programmazione Lineare, sort di piccoli array)

33 PIDGIN C NEL CORSO DESCRIVIAMO ALGORITMI
(ma per farlo di solito scriveremo dei programmi in C!) L'IMPORTANTE E' CHE LE AZIONI DESCRITTE SIANO BEN DEFINITE EFFICACI PER BEN DEFINIRE UNA OPERAZIONE SI POSSONO UTILIZZARE LINGUAGGI DI PROGRAMMAZIONE, e.g. C ALTRI LINGUAGGI (, , |, , , #, ...) (l'operatore # applicato a un insieme, lista, … ne ritorna la cardinalita') AL LIMITE L'ITALIANO  PIDGIN C CIO' SI APPLICA ANCHE A STRUTTURE DATI (e.g. INSIEMI) OCCORRE PERO' SEMPRE VERIFICARE CHE LE AZIONI DESCRITTE SIANO EFFICACI E INDICARNE L'ORDINE DI COMPLESSITA'


Scaricare ppt "Che cosa e' un algoritmo e come vogliamo studiare gli algoritmi?"

Presentazioni simili


Annunci Google