Un algoritmo realizza una relazione funzionale tra i valori di input e quelli di output

Documenti analoghi
Tempo e spazio di calcolo

Rappresentazione con i diagrammi di flusso (Flow - chart)

Algoritmi (9 CFU) (A.A ) Heap e Algoritmo HeapSort. Prof. V. Cutello Algoritmi 1

Tempo e spazio di calcolo (continua)

Algoritmi e Strutture Dati. Capitolo 4 Ordinamento

Formalismi per la descrizione di algoritmi

PROGRAMMAZIONE STRUTTURATA

Esercizi di Algoritmi e Strutture Dati

Le Funzioni e la Ricorsione

Diagrammi di flusso. Un metodo per rappresentare graficamente gli algoritmi. sotto programma. Input/ Output. Start. predicato Elaborazione Stop

Il problema delle azioni

QUICKSORT. Basato sul paradigma divide-et-impera (come MERGE-SORT)

Informatica/ Ing. Meccanica/ Prof. Verdicchio/ 14/02/2012 / Foglio delle domande / VERSIONE 1

Le strutture di controllo in C++

Strutture di controllo in C++

La principale modalità di calcolo è l applicazione di funzioni

= < < < < < Matematica 1

Due algoritmi di ordinamento. basati sulla tecnica Divide et Impera: Mergesort e Quicksort

Compitino di Laboratorio di Informatica CdL in Matematica 13/11/2007 Teoria Compito A

Esercizi di Algoritmi e Strutture Dati

Progetto e analisi di algoritmi

Albero di Riscorsione

Algoritmi e Strutture Dati

Sommario. Ordinamento. Selection Sort Bubble Sort/ Shaker Sort Shell Sort

Di cosa parliamo oggi?

Corso di Fondamenti di Informatica. La ricorsione

Programmazione Funzionale

Un tipico esempio è la definizione del fattoriale n! di un numero n, la cui definizione è la seguente:

Laboratorio di Programmazione

Corso di Fondamenti di Informatica Classi di istruzioni 2

LA LOGICA DI HOARE. Corso di Logica per la Programmazione A.A. 2010/11 Andrea Corradini, Paolo Mancarella

Introduzione alla programmazione Esercizi risolti

Alberi. Se x è il genitore di y, allora y è un figlio di x. Un albero binario è un albero in cui ogni nodo ha al massimo due figli.

Esercitazione 4. Comandi iterativi for, while, do-while

Laboratorio di Programmazione Lezione 2. Cristian Del Fabbro

Corso di Informatica

Linguaggi. Claudio Sacerdoti Coen 29,?/10/ : La struttura dei numeri naturali. Universitá di Bologna

Algoritmi e basi del C Struttura di un programma

Istruzioni iterative (o cicliche)

Cicli ed asserzioni. Ordinamento. Dato un intero positivo n ed una sequenza di n elementi a 1,...,a n

Tipici tempi di esecuzione. Martedì 7 ottobre 2014

04 - Logica delle dimostrazioni

Algoritmi e Strutture Dati Esercizi Svolti. Giuseppe Persiano Dipartimento di Informatica ed Appl. Renato M. Capocelli Università di Salerno

Cosa si intende con stato

L algoritmo AKS. L algoritmo AKS. Seminario per il corso di Elementi di Algebra Computazionale. Oscar Papini. 22 luglio 2013

in termini informali: un algoritmo è una sequenza ordinata di operazioni che risolve un problema specifico

Esercizi Capitolo 10 - Code con priorità e insiemi disgiunti

Ricorsione. La ricorsione consiste nella possibilità di definire una funzione in termini di se stessa

Esercizi sulla complessità di frammenti di pseudo-codice

Esercizi di Algoritmi e Strutture Dati

Introduzione alla programmazione Algoritmi e diagrammi di flusso. Sviluppo del software

Analisi e Programmazione

Indice. Prefazione. 3 Oggetti e Java 53

DIPARTIMENTO DI ELETTRONICA, INFORMAZIONE E BIOINGEGNERIA. INFORMATICA B Ingegneria Elettrica. La ricorsione

Laboratorio di Algoritmi e Strutture Dati

Costrutti condizionali e iterativi

Informatica/ Ing. Meccanica/ Edile/ Prof. Verdicchio/ 17/01/2014/ Foglio delle domande / VERSIONE 1

Fondamenti di Programmazione

Problema del cammino minimo

Programma del corso. Elementi di Programmazione. Introduzione agli algoritmi. Rappresentazione delle Informazioni. Reti di Calcolatori

RISOLUZIONE DI SISTEMI LINEARI

Cammini minimi fra tutte le coppie

Note per la Lezione 4 Ugo Vaccaro

Linguaggio C - le strutture di controllo: sequenza, selezione, iterazione

Algoritmi e strutture dati

Programmazione I - corso B a.a prof. Viviana Bono

Esercizio 1: Problema. Risoluzione Esercizi. Esercizio 1: Flow Chart

Un esempio per iniziare. Il controllo del programma in C. Altri cenni su printf() Esercizi (printf) printf( 8!=%d, fatt);

Corso di Informatica di Base

Matlab. Istruzioni condizionali, cicli for e cicli while.

Appunti di informatica. Lezione 7 anno accademico Mario Verdicchio

Dati e Algoritmi 1: A. Pietracaprina. Grafi (II parte)

Problemi, istanze, soluzioni

Linguaggi di programmazione - Principi e paradigmi 2/ed Maurizio Gabbrielli, Simone Martini Copyright The McGraw-Hill Companies srl

Ordinamenti per confronto: albero di decisione

Le Strutture di controllo Del Linguaggio C. Prof. Francesco Accarino IIS Altiero Spinelli Sesto San Giovanni

Università di Roma Tor Vergata L6-1. iterazione: struttura di controllo per ripetere più volte uno stesso comando

Corso di Fondamenti di Informatica

QuickSort (1962, The Computer Journal)

Ottimizzazione dei Sistemi Complessi

Politecnico di Torino Sede di Alessandria Corso di informatica Programmazione in c: introduzione. e mail: sito: users.iol.

UNIVERSITÀ DEGLI STUDI DI PAVIA FACOLTÀ DI INGEGNERIA. Matlab: esempi ed esercizi

Dati e Algoritmi I (Pietracaprina) Esercizi sugli Alberi

Esempi di Problemi Iterativi

unità didattica 3 Le strutture condizionali e le strutture iterative

Il concetto di calcolatore e di algoritmo

Risoluzione Esercizi. Esercizio 1: Flow Chart

AUTOMA A STATI FINITI

TABELLA OPERATORI ARITMETICI

Ricorsione. Unità 5. Domenico Daniele Bloisi. Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni BCOR Ingegneria Elettronica BELR

Esercitazione 6. Array

PROGRAMMAZIONE: Le strutture di controllo

Esempi di Problemi Iterativi

Esercizio 2 (punti 7) Dato il seguente programma C: #include <stdio.h> int swap(int * nome, int length);

Verifica parte IIA. Test (o analisi dinamica) Mancanza di continuità. Esempio

RAPPRESENTAZIONE GLI ALGORITMI NOTAZIONE PER LA RAPPRESENTAZIONE DI UN ALGORITMO

Collaudo del software

Corso: Fondamenti di Informatica 1 (gruppo 8-9) Corsi di laurea: Area dell'informazione Questionario di autovalutazione 4

Note su quicksort per ASD (DRAFT)

Programmazione strutturata

Transcript:

Un algoritmo realizza una relazione funzionale tra i valori di input e quelli di output F = { (s, s ) } per ogni s esiste una e una sola coppia (s, s ). Esempio: un algoritmo che calcola il quadrato di un numero naturale è descritto dal seguente insieme di coppie: {(0, 0), (1, 1), (2, 4), (3, 9), (4, 16)... }.

insieme di coppie infinito predicati della logica per caratterizzare le coppie di input/output {(x, z) / x N & z = x. x } Specifica di un algoritmo: espressione non ambigua dei requisiti funzionali che l algoritmo deve soddisfare.

Algoritmo A variabili di input: x1, x2,..., xn ( x ) variabili di output: z1, z2,...,zk ( z ) Specifica di A è una coppia di predicati: < p-in(x), p-out(x, z)>, dove: p-in(x): predicato di input di A, specifica i vincoli cui devono soddisfare i valori forniti per le variabili di input (il dominio delle variabili); p-out(x, z): predicato di output di A, specifica la relazione di input / output.

quadrato di un numero naturale p-in(x) x 0 p-out(x, z) z = x. x moltiplicazione di x1 per x2 p-in(x1, x2) x1 0 & x2 0 p-out(x1, x2, z) z = x1. x2 quoziente e il resto della divisione di x1 per x2 p-in(x1, x2) x1 0 & x2 > 0 p-out(x1, x2, z1, z2) x1 = z1. x2 + z2 & 0 z2 < x2

Correttezza parziale Dato un algoritmo A e una specifica < p-in(x), p-out(x, z)> A si dice parzialmente corretto rispetto alla specifica se per ogni valore a delle variabili di input x, che soddisfa il predicato di input, se l algoritmo termina, termina con valore b per le variabili di output z, che soddisfa il predicato p-out(a, b).

Terminazione Dato un algoritmo A e un predicato di input p-in(x), si dice che A termina su p-in(x) se per ogni valore a delle variabili di input x, che soddisfa il predicato di input, l algoritmo termina.

Correttezza totale Dato un algoritmo A e una specifica < p-in(x), p-out(x, z)> A si dice totalmente corretto rispetto alla specifica se è parzialmente corretto rispetto alla specifica e termina sul predicato di input.

Verifica della correttezza parziale La correttezza parziale di un algoritmo A rispetto alla specifica <p-in(x), p-out(x, z)> è espressa dalla Formula di correttezza di Hoare: { p-in(x) } A { p-out (x, z) } p-in(x) p-out(x, z) { } A { }

{ p-in(x1, x2) x1 0 & x2 0 } Prodotto { p-out(x1, x2, z) z = x1. x2 }

{ p-in(x) x 0 } Incremento (x) 1 z x 2 z z + 1 3 return z { p-out(x, z) z > 0 }

{ p-in(x) x 0 } Incremento (x) { x 0 } x 0 x +1 > 0 1 z x z +1 > 0 2 z z + 1 { z > 0 } z > 0 3 return z { p-out(x, z) z > 0 } per ogni valore 0 assunto da x alla chiamata del metodo, al rientro il valore di z sarà > 0

z = x z 0 & (z = x z = - x) { } modulo (x) 1 if x 0 then { x 0 } 2 z x { x 0 & z 0 & z = x} else { x < 0 } 3 z - x { x < 0 & z > 0 & z = - x} { z 0 & (z = x z = - x) } 4 return z { p-out(x, z) z = x } p-in(x) true

then { x 0 } x 0 & x 0 & x = x z x { x 0 & z 0 & z = x} else { x < 0 } x < 0 & -x > 0 & -x = - x z - x { x < 0 & z > 0 & z = - x} { z 0 & (z = x z = - x) }

{x1 0 & x2 0 } moltiplicazione (x1, x2) y x1 z 0 while y > 0 do z z + x2 y y - 1 return z {z = x1. x2 }

{x1 0 & x2 0 } moltiplicazione (x1, x2) {x1 0 & x2 0} x1. x2 = x1. x2 + 0 & x1 0 y x1 z 0 {x1. x2 = y. x2 + z & y 0} while y > 0 do z z + x2 y y - 1 return z {z = x1. x2 }

{x1 0 & x2 0 } moltiplicazione (x1, x2) y x1 z 0 {x1. x2 = y. x2 + z & y 0} while y > 0 do {x1. x2 = y. x2 + z & y > 0} z z + x2 y y - 1 {x1. x2 = y. x2 + z & y 0} return z {z = x1. x2}

x1. x2 = (y-1). x2 + x2 + z & y-1 0 {x1. x2 = y. x2 + z & y > 0} z z + x2 y y - 1 {x1. x2 = y. x2 + z & y 0}

E dopo l esecuzione del while, se termina: {x1 0 & x2 0} moltiplicazione (x1, x2) y x1 z 0 { x1. x2 = y. x2 + z & y 0 } while y > 0 do { x1. x2 = y. x2 + z & y > 0} z z + x2 y y - 1 { x1. x2 = y. x2 + z & y 0 } { x1. x2 = y. x2 + z & y = 0 } return z {z = x1. x2}

Difficoltà: esprimere il predicato che si mantiene vero durante l esecuzione del ciclo: Invariante di ciclo y 45 19 44 19 43 z 19.. 3 19 2 19 1 19 y: valori della prima colonna z : somma parziale Ad esempio: 855 = 3 x 19 + 798 x1 x x2 y x x2 z 855

Moltiplicazione alla russa y1 y2 45 19 22 38 19 --- z z: somma parziale y1: valori della prima colonna y2: valori della seconda colonna y1 11 76 5 152 2 304 1 608 76 152 --- 608 Ad esempio: 855 = 5 x 152 + 95 x1 x x2 y1 x y2 z y2 855

{ x1 0 & x2 0 } molt-russa (x1, x2) y1 x1 y2 x2 z 0 { x1. x2 = y1. y2 + z & y1 0 } while y1 > 0 do { x1. x2 = y1. y2 + z & y1 > 0 } if y1 is odd then z z + y2 y1 y1 div 2 y2 y2 + y2 { x1. x2 = y1. y2 + z & y1 0 } { x1. x2 = y1. y2 + z & y1 = 0 } return z { z = x1. x2 }

x1. x2 = x1. x2 + 0 & x1 0 { x1 0 & x2 0 } y1 x1 y2 x2 z 0 { x1. x2 = y1. y2 + z & y1 0 }

x1. x2 = (y1 div 2). (y2 + y2) + z se y1 pari (y1 div 2). (y2 + y2) + (z + y2) se y1 dispari & y1 div 2 0 { x1. x2 = y1. y2 + z & y1 > 0 } if y1 is odd then { x1. x2 = y1. y2 + z & y1 > 0 & y1 dispari} z z + y2 y1 y1 div 2 y2 y2 + y2 { x1. x2 = y1. y2 + z & y1 0 }

2n x m = n x 2m (2n + 1) x m = 2n x m + m = n x 2m + m y1. y2 = (y1 div 2). (y2 + y2) se y1 pari y1. y2 = (y1 div 2). (y2 + y2) + y2 se y1 dispari x1. x2 = y1. y2 + z & y1 > 0 x1. x2 = (y1 div 2). (y2 + y2) + z se y1 pari (y1 div 2). (y2 + y2) + (z + y2) se y1 dispari

{ x1 0 & x2 0 } molt-russa (x1, x2) y1 x1 y2 x2 z 0 { x1. x2 = y1. y2 + z & y1 0 } while y1 > 0 do if y1 is odd then z z + y2 y1 y1 div 2 y2 y2 + y2 return z { z = x1. x2 }

{ x1 0 & x2 > 0 } divisione (x1, x2) q 0 r x1 { x1 = q. x2 + r & 0 r & x2 > 0 } while r x2 do { x1 = q. x2 + r & 0 r & x2 > 0 & r x2 } q q + 1 r r - x2 { x1 = q. x2 + r & 0 r & x2 > 0 } { x1 = q. x2 + r & 0 r & r < x2 } return (q, r) { x1 = q. x2 + r & 0 r < x2 }

x1 0 & x2 > 0 q 0 r x1 x1 = 0. x2 + x1 & 0 x1 & x2 > 0 x1 = q. x2 + r & 0 r & x2 > 0 & r x2 q q + 1 r r - x2 x1 = (q + 1). x2 + (r - x2) & 0 (r - x2) & x2 > 0 }

Il costrutto for: for i a to b do S supponiamo che: - gli estremi a e b siano numeri naturali - a b - passo uno. il costrutto for e` equivalente a: i a while i b do S i i + 1

{ n 1 } n = length[a] Massimo (A, n) current-max A[0] i 1 { current-max A[j], per ogni j, 0 j < i } for i 1 to n-1 do while i < n do if current-max < A[i] then current-max A[i] i i + 1 { current-max A[j], per ogni j, 0 j < n } return current-max { current-max è il massimo tra gli elementi di A }

P(x) = a 0 + a 1 x+ + a n x n n = grado del polinomio { n 1} Poly-eval (A, x, n) y 1 result A[0] i 1 { result = A[0] + A[1] x +... + A[i-1] x i-1 & y = x i-1 } for i 1 to n do y y x result result +A[i] y i i +1 return result { result = A[0] + A[1] x +... + A[n] x n }

P(x) = a 0 + x (a 1 + + x (a n-1 + x a n )) ) { n 1} Horner (A, x, n) result A[n] i n - 1 {result = A[i+1] + A[i+2] x +... + A[n] x n-(i+1) } for i n - 1 downto 0 do result result x + A[i] i i - 1 {result = A[i+1] + A[i+2] x +... + A[n] x n-(i+1) } return result {result = A[0] + A[1] x +... + A[n] x n }

Metodi ricorsivi { n 1} Massimo-ricorsivo (A, n) if n = 1 then current-max A[0] return current-max y Massimo-ricorsivo (A, n-1) current-max max (y, A[n-1]) return current-max n = length[a] { current-max è il massimo tra gli elementi di A} T(n) = h se n = 1 T(n-1) + k altrimenti

{ n = 1} current-max A[0] return current-max {current-max è il massimo tra gli elementi di A} n = 1 A[0] è il massimo tra gli elementi di A

{ n > 1} y Massimo-ricorsivo (A, n-1) current-max max (y, A[n-1]) return current-max { current-max è il massimo tra gli elementi di A} La correttezza viene verificata supponendo che la chiamata interna funzioni bene e dimostrando che le modifiche subite dalle variabili rendono vero il predicato.

{ n > 1} y Massimo-ricorsivo (A, n-1) current-max max (y, A[n-1]) return current-max { current-max è il massimo tra gli elementi di A} Supponiamo che Massimo-ricorsivo su un numero di elementi < n lavori correttamente: { n > 1} y Massimo-ricorsivo (A, n-1) { current-max è il massimo tra gli elementi di A[0..n-2]}

{ n > 1} y Massimo-ricorsivo (A, n-1) { current-max è il massimo tra gli elementi di A[0..n-2] } current-max max (y, A[n-1]) { current-max è il massimo tra gli elementi di A[0..n-1] } return current-max { current-max è il massimo tra gli elementi di A} La dimostrazione di correttezza per i metodi ricorsivi viene fatta per induzione sul numero di chiamate.

{ p 0 & r 0 & p r} DI-Massimo-ricorsivo (A, p, r) if p = r then current-max A[p] return current-max if p = r-1 then if A[p] < A[r] then current-max A[r] return current-max else current-max A[p] return current-max q (p + r)/2 current-max-1 DI-Massimo-ricorsivo (A, p, q) current-max-2 DI-Massimo-ricorsivo (A, q +1, r) current-max max(current-max1, current-max2) return current-max { current-max è il massimo tra gli elementi di A}

La correttezza e` facile da verificare. Piu` difficile valutarne la complessita` esprimiamo la complessita` come relazione di ricorrenza: T(1) = c (p = q) T(2) = d (p = q-1) T(n) = T( n/2 ) + T( n/2 ) + e (p < q-1) Anche per l algoritmo ricorsivo la complessita` e` Θ(n), come per l algoritmo iterativo visto in precedenza.