Sistemi e Tecnologie Informatiche Complessità di calcolo.

Slides:



Advertisements
Presentazioni simili
INFORMATICA Altre Istruzioni di I/O
Advertisements

Algoritmi e Strutture Dati
INFORMATICA Algoritmi fondamentali
Linguaggi algoritmici
Iterazione while – do while - for.
Iterazione A. Ferrari.
Procedure e funzioni A. Ferrari.
Procedure e funzioni ricorsive
© 2007 SEI-Società Editrice Internazionale, Apogeo Unità F3 Iterazione.
Universita di Camerino
MATLAB.
MATLAB. Scopo della lezione Programmare in Matlab Funzioni Cicli Operatori relazionali Esercizi vari.
Algoritmi e Programmazione
Introduzione agli algoritmi. Definizione Sistema di regole e procedure di calcolo ben definite che portano alla soluzione di un problema con un numero.
Capitolo 4 Ordinamento Algoritmi e Strutture Dati.
Gestione dei dati e della conoscenza (agenti intelligenti) M.T. PAZIENZA a.a
Sistemi basati su conoscenza Metodi di ricerca informata Prof. M.T. PAZIENZA a.a
PROGRAMMI DI RICERCA E ORDINAMENTO
Algoritmi Politecnico di Milano C Primi programmi Politecnico di Milano.
Capitolo 4 Ordinamento Algoritmi e Strutture Dati.
1 Corso di Informatica (Programmazione) Lezione 11 (19 novembre 2008) Programmazione in Java: controllo del flusso (iterazione)
Corso di Informatica (Programmazione)
1 Corso di Laurea in Biotecnologie Informatica (Programmazione) Problemi e algoritmi Anno Accademico 2009/2010.
Algoritmi e Strutture Dati (Mod. A)
1 2. Analisi degli Algoritmi. 2 Algoritmi e strutture dati - Definizioni Struttura dati: organizzazione sistematica dei dati e del loro accesso Algoritmo:
Introduzione1 Algoritmi e strutture dati - Definizioni Struttura dati: organizzazione sistematica dei dati e del loro accesso Algoritmo: procedura suddivisa.
Modelli simulativi per le Scienze Cognitive
INFORMATICA Altre Istruzioni di I/O. © Piero Demichelis 2 Funzioni di I/O Per la lettura e la scrittura da videoterminale il C prevede numerose istruzioni.
Strutture di controllo in C -- Flow Chart --
Algoritmi e Programmazione (in C) Stefano Cagnoni e Monica Mordonini
Elementi di Informatica di base
Sistemi e Tecnologie Informatiche
INFORMATICA MATTEO CRISTANI.
Radix-Sort(A,d) // A[i] = cd...c2c1
Algoritmi e Strutture Dati
Un esempio: Calcolo della potenza n-esima di un numero reale
Analisi di un algoritmo
Complessità di un algoritmo
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 1 Cicli ed asserzioni Corso di Informatica 2 a.a. 2003/04 Lezione 1.
Sistemi e Tecnologie Informatiche Ricorsione Umberto Ferraro Petrillo.
Sistemi e Tecnologie Informatiche
Ripetizione La vera potenza dei programmi per computer risiede nella capacità di ripetere lo stesso calcolo o sequenza di istruzioni più volte, ogni volta.
Sistemi e Tecnologie Informatiche Verifica di correttezza di un programma.
R 255 G 211 B 8 R 255 G 175 B 0 R 127 G 16 B 162 R 163 G 166 B 173 R 104 G 113 B 122 R 234 G 234 B 234 R 175 G 0 B 51 R 0 G 0 B 0 R 255 G 255 B 255 Supporting.
La ricorsione.
Capitolo 6 Iterazione Lucidi relativi al volume: Java – Guida alla programmazione James Cohoon, Jack Davidson Copyright © The McGraw-Hill Companies.
Informatica B Allievi Elettrici - AA Fondamenti della programmazione in linguaggio C (II) Istruzioni e strutture di controllo.
1 Fabio Scotti – Università degli Studi di Milano Fabio Scotti ( ) Laboratorio di programmazione per la sicurezza Valentina Ciriani ( )
Fondamenti di Informatica II Ingegneria Informatica Prof. M.T. PAZIENZA a.a – 3° ciclo.
13 ottobre Decisioni F. Bombi 13 ottobre 2002.
Il problema della ricerca Algoritmi e Strutture Dati.
Scrivere e compilare programmi
1 Ordinamento (Sorting) INPUT: Sequenza di n numeri OUTPUT: Permutazione π = tale che a 1 ’  a 2 ’  … …  a n ’ Continuiamo a discutere il problema dell’ordinamento:
Sistemi basati su conoscenza Metodi di ricerca informata Prof. M.T. PAZIENZA a.a
Linguaggio C: Le basi Stefano Cagnoni e Monica Mordonini
1 Macchine astratte, linguaggi, interpretazione, compilazione.
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Algoritmi e Strutture Dati Capitolo 2 Modelli di calcolo e metodologie.
Linguaggio C: Le basi Stefano Cagnoni e Monica Mordonini
L’ELABORATORE ELETTRONICO uno strumento in grado di eseguire insiemi di azioni (“mosse”) elementari le azioni vengono eseguite su oggetti (dati) per produrre.
1 Ordinamento (Sorting) Input: Sequenza di n numeri Output: Permutazione π = tale che: a i 1  a i 2  ……  a i n Continuiamo a discutere il problema dell’ordinamento:
Algoritmi e Programmazione (in C) Stefano Cagnoni e Monica Mordonini
Informatica e Informatica di Base
Informatica 4 La ricorsione. Definizione di ricorsione Ricorsione è la proprietà di quei programmi che, all’interno delle istruzioni che li compongono,
Complessità Computazionale
Problema dell’Ordinamento. Problema dell’ordinamento Formulazione del problema –Si vuole ordinare una lista di elementi secondo una data proprietà P Esempio:
Informatica 3 V anno.
Informatica Problemi e algoritmi. una situazione che pone delle domande cui si devono dare risposte. Col termine problema o situazione problematica s’indica.
Dal problema al programma – ciclo di sviluppo del software La scrittura del programma è solo una delle fasi del processo di sviluppo di un'applicazione.
Lezioni di Ricerca Operativa Corso di Laurea in Informatica
Lezione n. Parole chiave: Corso di Laurea: Insegnamento: Docente: A.A Salvatore Cuomo La ricorsione 15 Approccio ricorsivo, esercizi sulla.
Transcript della presentazione:

Sistemi e Tecnologie Informatiche Complessità di calcolo

#include int main(void) { int numero1 = 5; int numero2 = 0; if (numero1==numero2) printf(“I due numeri coincidono\n"); return 0; } #include int main(void) { int numero1 = 5; int numero2 = 0; int numero3 = 8; int numero4 = 12; printf(“La somma dei numeri è %d\n", numero1+numero2+numero3+numero4); printf(“Il prodotto dei numeri è %d\n", numero1*numero2*numero3*numero4); return 0; }

#include int main(void){ printf(“I primi numeri naturali sono: \n"); for(int i=0;i<10000;i++) printf(“%d “, i); } #include int main(void) { int numero1 = 5; int numero2 = 0; int numero3 = 8; int numero4 = 12; printf(“La somma dei numeri è %d\n", numero1+numero2+numero3+numero4); printf(“Il prodotto dei numeri è %d\n", numero1*numero2*numero3*numero4); return 0; }

In questa lezione impareremo che … La nozione di efficienza è fondamentale ai fini della valutazione di un algoritmo Esistono due valutazioni di efficienza: Tempo di calcolo Quantità di memoria necessaria E’ possibile valutare l’efficienza di un algoritmo ( … e di un programma) attraverso l’analisi della complessità

Intuitivamente … Un algoritmo (programma) si può definire “efficiente” se richiede “poche” risorse di calcolo Un algoritmo si può definire ottimale per la risoluzione di un problema se, tra tutti gli algoritmi esistenti, è quello che risolve il problema in modo più efficiente

Intuitivamente … Le due principali caratteristiche per la valutazione dell’efficienza di un algoritmo sono: il tempo totale di esecuzione la quantità totale di memoria necessaria all’esecuzione

Misuriamo l’efficienza di un algoritmo Implementiamolo Scegliamo dei dati in input Armiamoci di cronometro Eseguiamo il programma su un calcolatore e misuriamo il tempo totale di esecuzione “Se il programma ha richiesto poco tempo è efficiente, se richiede molto tempo è inefficiente”

Confrontiamo l’efficienza di algoritmi diversi Implementiamo un secondo algoritmo Scegliamo dei dati in input Ricicliamo il cronometro del test precedente Eseguiamo il nuovo programma su un calcolatore e misuriamo il tempo totale di esecuzione “Se l’implementazione del secondo algoritmo ha richiesto meno tempo del precedente è più efficiente, diversamente è meno efficiente”

Misuriamo l’efficienza di un algoritmo L’approccio appena proposto è palesemente scorretto! Esso non tiene conto del fatto che i tempi di esecuzione di un programma sono influenzati: Dal compilatore utilizzato per tradurre in programma il codice sorgente dell’algoritmo Dal calcolatore utilizzato per l’esecuzione del programma Dalla significatività dei dati in input … e da una miriade di altri fattori!

Misuriamo l’efficienza di un algoritmo Un approccio più rigoroso potrebbe quindi consistere nel : Selezionare un insieme di dati di input significativi Utilizzare lo stesso compilatore per tutti i programmi Utilizzare lo stesso calcolatore per tutti i test ed infine Eseguire gli stessi test per tutti i programmi

Misuriamo l’efficienza di un algoritmo Il tempo di esecuzione di un algoritmo non è spesso una misura affidabile dell’efficienza di un algoritmo Le misurazioni operate, seppure rigorose, sono poco generalizzabili E’ preferibile un tipo di valutazione più astratto che, senza entrare nel merito di compilatori e calcolatori, sappia stimare la quantità complessiva di lavoro richiesta da un algoritmo per risolvere un certo problema

Misuriamo l’efficienza di un algoritmo La quantità di lavoro richiesta per l’esecuzione di un algoritmo può essere descritta come l’insieme di istruzioni che esso esegue Più istruzioni ci sono, più i tempi di esecuzione si allungano L’algoritmo ottimale è quello che richiede l’esecuzione di meno istruzioni Per valutare l’insieme di istruzioni eseguito da un algoritmo ne scorriamo il codice e “contiamo” una ad una le istruzioni che saranno eseguite

Un primo esempio … #include int main(void) { int numero1 = 5; int numero2 = 0; if (numero1==numero2) printf(“I due numeri coincidono\n"); return 0; } Totale istruzioni: 5 #include int main(void) { int numero1 = 5; int numero2 = 0; int numero3 = 8; int numero4 = 12; printf(“La somma dei numeri è %d\n", numero1+numero2+numero3+numero4); printf(“Il prodotto dei numeri è %d\n", numero1*numero2*numero3*numero4); return 0; } Totale istruzioni: 7

Un esempio più complesso! #include int main(void){ int ultimo_numero, penultimo_numero, int i, conta_numeri; i=1; conta_numeri=0; scanf("%d", &penultimo_numero); while(i<=9) { scanf("%d", &ultimo_numero); if( penultimo_numero<ultimo_numero ) conta_numeri++; penultimo_numero=ultimo_numero; i++; } printf("%d\n", conta_numeri); return 0; }

Regole per la misurazione dell’efficienza di un algoritmo 1. Il costo di esecuzione di una istruzione semplice è 1 2. Il costo di esecuzione di un ciclo (while,for) è dato dalla somma del costo totale di esecuzione della condizione di test e dalla somma del costo totale di esecuzione del corpo del ciclo int numero1 = 5; int numero2 = 0; numero1 = numero2+1; for (int i = 0; i < 5; i++) { numero1 = numero1+1; numero2 = numero2+1; } x1 5x(1+1)

Regole per la misurazione dell’efficienza di un algoritmo 1. Il costo di esecuzione di una istruzione condizionale (if) è dato dal costo di esecuzione del test più il costo di esecuzione dell’istruzione eseguita nel caso la condizione sia vera 2. Il costo di esecuzione di una funzione è pari al costo di esecuzione di tutte le istruzioni che la compongono if (numero1 > 0) printf(“Numero positivo”); 1111 void positivo(int numero1) { if (numero1 > 0) printf(“Numero positivo”); } 1111

Un esempio più complesso! #include int main(void){ int ultimo_numero, penultimo_numero, int i, conta_numeri; i=1; conta_numeri=0; scanf("%d", &penultimo_numero); while(i<=9) { scanf("%d", &ultimo_numero); if( penultimo_numero<ultimo_numero ) conta_numeri++; penultimo_numero=ultimo_numero; i++; } printf("%d\n", conta_numeri); return 0; }

Ancora più complesso! int PosizioneElemento(int Voti[], int elem, int n) /* Effettua la ricerca esaustiva di elem tra i primi n elementi di Voti. Il valore di ritorno e` -1 se elem non e` presente in Voti, altrimenti e` l'indice della posizione di elem. */ { int i = 0; // Verifichiamo se la fine dell’elenco è stata raggiunta // o se l’elemento corrente coincide con quello cercato while ( i<n-1 && Voti[i] != elem) i++; // Consideriamo il prossimo elemento if (Voti[i] == elem) return i; // L’elemento è stato individuato else return -1; // L’elemento non è presente } Non conosciamo a priori la taglia dei dati in input (e.g., il numero dei voti tra cui cercare l’elemento) E’ ancora possibile calcolare il costo di esecuzione dell’algoritmo anche se questo sarà espresso in funzione della taglia dell’input (n) Nel caso in esame 1 + 2n + 2 = 3 + 2n

Nota Non è sempre possibile conoscere a priori quali e quante istruzioni un programma eseguirà dal momento che il suo comportamento è condizionato dai dati in input che utilizziamo Esistono quindi dati di input per i quali l’esecuzione si arresta subito, e dati di input per i quali l’esecuzione può richiedere molto tempo Nella valutazione dell’efficienza di un algoritmo si è spesso interessati a sapere come si comporta lo stesso: nel caso migliore, considerando i dati di input che minimizzano il numero di istruzioni da eseguire nel caso peggiore, considerando i dati di input che massimizzano il numero di istruzioni da eseguire

Complessità Dato un algoritmo, quando non è possibile conoscere in partenza il tipo di input che si elabora, si procede con la valutazione del caso peggiore Valuteremo perciò il costo di esecuzione di un programma come: il conteggio delle istruzioni che esso esegue in funzione della dimensione dell’input con riferimento al caso peggiore

Valutazione di costo int PosizioneElemento(int Voti[], int elem, int n) /* Effettua la ricerca esaustiva di elem tra i primi n elementi di Voti. Il valore di ritorno e` -1 se elem non e` presente in Voti, altrimenti e` l'indice della posizione di elem. */ { int i = 0; // Verifichiamo se la fine dell’elenco è stata raggiunta // o se l’elemento corrente coincide con quello cercato while ( i<n-1 && Voti[i] != elem) i++; // Consideriamo il prossimo elemento if (Voti[i] == elem) return i; // L’elemento è stato individuato else return -1; // L’elemento non è presente } Caso migliore (i.e., troviamo subito l’elemento): f(n) = 4 Caso peggiore (i.e., l’elemento non è presente) f(n) = 1 + 2n +2 = 3 + 2n

Confrontare due algoritmi Come è possibile trarre vantaggio dalla conoscenza del costo (complessità) di due algoritmi per decidere quali dei due è migliore? E.g. A e B sono algoritmi di ordinamento di elenchi, sia n la taglia dell’elenco di input L’algoritmo A esegue n istruzioni L’algoritmo B esegue n istruzioni L’algoritmo C esegue 6 + 2n 2 istruzioni n (A) > n (B)

In sintesi … Le tecniche di analisi del costo di esecuzione di un algoritmo introdotte: operano delle assunzioni esemplificative (e.g., tutte le istruzioni semplici hanno lo stesso costo di esecuzione) determinano esattamente il numero complessivo di istruzioni da eseguire in corrispondenza di un determinato input L’analisi di algoritmi particolarmente complessi può rivelarsi tuttavia difficoltosa per via dell’eccessiva lunghezza ed ingestibilità dell’equazione risultante In questi casi siamo interessati ad ottenere una stima approssimata che sia più facile da gestire