Dimostrazioni, induzione e invarianti
In questa pagina 4
Servono per le analisi di complessità e di correttezza (l'algoritmo termina e risolve il problema computazionale, vedi Problemi computazionali e algoritmiProblema computazionale come insieme di coppie (istanza, soluzione); algoritmo e modello di calcolo RAM; pseudocodice; taglia di un'istanza; ADT e struttura dati concreta; esempio svolto con ricerca lineare e binaria in un array ordinato.Problemi computazionali e algoritmi →). Le tecniche sono quelle di Analisi 1 (Tecniche di dimostrazioneDimostrazione diretta, per contronominale e per assurdo di un teorema del tipo ipotesi implica tesi.Tecniche di dimostrazione →, Principio di induzionePer dimostrare una proprietà per ogni n basta il passo base e il passo induttivo da n a n+1.Principio di induzione →, Logica e quantificatoriProposizioni, connettivi, predicati e quantificatori (per ogni, esiste), con le regole per negarli.Logica e quantificatori →): qui si applicano agli algoritmi. In particolare gli enunciati "per ogni abbastanza grande" e "esiste un'istanza" delle analisi di complessità sono quantificatori ed , e il modo di provarli è diverso: un richiede una dimostrazione valida per ogni caso, un si prova esibendo un caso.
Esempio, controesempio, assurdo
- Esempio: per dimostrare che basta mostrare che per ogni abbastanza grande esiste un'istanza che richiede almeno operazioni (vedi Complessità in tempo e caso pessimoPerché lo studio sperimentale non basta; complessità al caso pessimo come massimo sul numero di operazioni tra le istanze di una data taglia; stima con limiti superiore e inferiore senza trovare l'istanza peggiore; esempi arrayMax, prefixAverages e InsertionSort; efficienza asintotica e limiti dell'analisi.Complessità in tempo e caso pessimo →).
- Controesempio: per confutare " è primo per ogni " (un enunciato ) basta un solo caso in cui è falso: . I casi ( e ) non lo smentiscono, ma non lo dimostrano nemmeno: verificare esempi non è una dimostrazione.
- Assurdo: si nega la tesi e si ottiene una contraddizione. Se è dispari, allora e sono dispari: se uno fosse pari, ad esempio (un numero è pari se è multiplo di ), allora sarebbe pari, contro l'ipotesi che sia dispari. La contraddizione dice che la negazione della tesi era impossibile.
Induzione
Teorema (principio di induzione). Per provare che vale per ogni :
- si sceglie (di solito );
- base: si dimostra ;
- passo: si fissa arbitrario e, assumendo vera per ogni con (ipotesi induttiva), si dimostra .
Il passo deve valere per ogni . Servono più casi base quando il passo usa più valori precedenti (Fibonacci usa i due precedenti: ).
Esempio 1. per (sommatorie: SommatorieIl simbolo di sommatoria, le sue proprietà (linearità, additività, cambio di indice) e le somme notevoli di Gauss e geometrica.Sommatorie →). Base : a sinistra c'è la somma del solo termine , cioè ; a destra . Passo: si suppone vera la formula per e si scrive la somma fino a isolando l'ultimo termine, dove si è messo a denominatore comune e raccolto . L'ultimo membro è proprio la formula con al posto di . ✓
Esempio 2 (Fibonacci). , , . Si prova con , . Base: (verifica diretta): per , ; per , , e . Servono due casi base perché il passo usa i due valori precedenti ed . Passo (): . Si osserva , perché : infatti . Allo stesso modo per : (i due numeri sono le radici di ). Quindi . ✓ (Verificato numericamente: .)
Esempio 3. : . Base : . Passo (si somma a entrambi i membri dell'ipotesi, poi si raccoglie , che compare in entrambi i termini): , dove l'ultimo passo è la scomposizione (verifica: ). Il risultato è la formula con al posto di , perché . ✓
Correttezza di un algoritmo
Schema generale: si individuano lo stato iniziale e quello finale desiderato, si scompone l'algoritmo in segmenti con uno stato atteso a fine segmento (checkpoint) e si prova che dallo stato iniziale si raggiungono in successione tutti i checkpoint; l'ultimo deve implicare lo stato finale. I segmenti notevoli sono i cicli. La terminazione si prova assicurandosi che cicli e ricorsione abbiano fine.
Invarianti di ciclo
Definizione (invariante di ciclo). Un invarianteProprietà sulle variabili del ciclo che descrive lo stato a ogni iterazione. è una proprietà delle variabili usate nel ciclo che:
- vale all'inizio del ciclo, come conseguenza dello stato iniziale (inizializzazione);
- vale alla fine di ogni iterazione, assumendo che valesse all'inizio di quella iterazione (conservazione);
- alla fine dell'ultima iterazione, insieme alla condizione di uscita, implica la correttezza del ciclo (uso).
Esempio. In arrayMax l'invariante «alla fine dell'iterazione , » vale all'inizio (), si conserva a ogni passo e a fine ciclo () dà il massimo dell'intero array.
Un ciclo esegue iterazioni del corpo; for i <- 1 to n ne fa sempre . Il legame con l'induzione è stretto: "vale all'inizio" è il caso base, "si conserva a ogni iterazione" è il passo induttivo, e le iterazioni successive sono il che cresce di .
arrayMax. currMax <- A[0]; for i <- 1 to n-1 do currMax <- max(currMax, A[i]). Invariante: alla fine dell'iterazione , . All'inizio ( prima del ciclo) = massimo di . Conservazione: il massimo di è il massimo tra il massimo di e . Alla fine () è il massimo di tutto l'array. Traccia su :
| dopo l'iterazione | |||
|---|---|---|---|
| (prima del ciclo) | 3 | 3 | |
| 1 | 7 | 7 | 7 |
| 2 | 2 | 7 | 7 |
| 3 | 9 | 9 | 9 |
| 4 | 4 | 9 | 9 |
Le due colonne finali coincidono a ogni riga: è ciò che afferma l'invariante.
Il più lungo segmento di 1 in una sequenza di bit :
max <- 0; curr <- 0
for i <- 1 to n do
if S[i] = 1 then
curr <- curr + 1
if curr > max then max <- curr
else curr <- 0
return maxInvariante alla fine dell'iterazione : (a) è la lunghezza del segmento di 1 che termina in (zero se ) e (b) è la lunghezza massima di un segmento di 1 in . Inizio (): sequenza vuota, entrambi . Conservazione: se il segmento che termina in estende quello che terminava in , quindi cresce di 1 e viene aggiornato se lo supera; se il segmento si interrompe e , mentre non cambia. Fine: per la (b) dà la risposta. (Controllato con un test casuale su sequenze di lunghezza .) Traccia su :
| 0 (inizio) | 0 | 0 | |
| 1 | 1 | 1 | 1 |
| 2 | 1 | 2 | 2 |
| 3 | 0 | 0 | 2 |
| 4 | 1 | 1 | 2 |
| 5 | 1 | 2 | 2 |
| 6 | 1 | 3 | 3 |
| 7 | 0 | 0 | 3 |
Alla fine , la lunghezza del segmento .
Cicli con due indici (esempio d'esame): in while (i < n) AND (j < m) su una matrice con colonne decrescenti, l'invariante lega il valore corrente a e ; si veda l'esercizio Esercizio 3 · invariante su matrice a colonne decrescenti.
Errori comuni
- Un invariante che vale solo alla fine (non è un invariante): deve valere anche all'inizio e dopo ogni iterazione.
- Un invariante troppo debole: non basta a concludere la correttezza all'uscita (es. "" non dice che sia il massimo).
- Nell'induzione: provare il passo solo per un specifico, o dimenticare uno dei casi base quando il passo usa due valori precedenti.
- Confondere ipotesi induttiva e tesi: nel passo si assume per e si prova .
Versione ripasso
- Tecniche: esempio (per un basta un' istanza cattiva); controesempio (basta un caso in cui l'enunciato è falso: ); assurdo (si nega la tesi e si trova una contraddizione: se è dispari, allora e sono dispari).
- Principio di induzione: per con : si sceglie ; base ; passo: assumendo per , si prova per ogni (vedi Principio di induzionePer dimostrare una proprietà per ogni n basta il passo base e il passo induttivo da n a n+1.Principio di induzione →).
- Gauss: ; passo: .
- Quadrati: ; passo: , usando .
- Fibonacci: con e . Servono due casi base () perché il passo usa e . Passo: , perché ; lo stesso vale per , radici di .
- Correttezza: stato iniziale checkpoint stato finale; la terminazione di cicli e ricorsione va provata a parte (vedi Problemi computazionali e algoritmiProblema computazionale come insieme di coppie (istanza, soluzione); algoritmo e modello di calcolo RAM; pseudocodice; taglia di un'istanza; ADT e struttura dati concreta; esempio svolto con ricerca lineare e binaria in un array ordinato.Problemi computazionali e algoritmi →).
- Invariante di ciclo: (1) vale prima della prima iterazione; (2) se vale prima di un'iterazione, vale dopo; (3) a fine ciclo, con la condizione di uscita, implica la tesi. Vale all'inizio come caso base e si conserva come passo induttivo.
- arrayMax: invariante dopo l'iterazione . Traccia su : , cioè il massimo del prefisso.
- Segmento di 1 in : = lunghezza del segmento di 1 che termina in (zero se ); = lunghezza massima in . Traccia su : alla fine.
- Schema per i cicli: un
for i <- 1 to nfa sempre iterazioni; la base dell'induzione è lo stato prima del ciclo, il passo è un singolo giro. - Errori tipici: invariante vero solo a fine ciclo o troppo debole (es. "" non dice che sia il massimo); passo induttivo non valido per ogni ; casi base mancanti quando il passo usa due valori; confondere ipotesi e tesi.
Esercizi su questo argomento
- Esercizio - convoluzione con il vettore delle potenze di due in tempo lineare (compito del 5 settembre 2025, es. 2)
- Esercizio - elemento (h,k) di una matrice supercircolante (esercizi su supercircolanti e circolanti, es. SC 5)
- Esercizio - matrici ARB, prodotto con tre chiamate ricorsive (compito del 19 giugno 2024, es. 1)
- Esercizio - matrici RCA, somma e prodotto matrice-vettore (compito del 18 giugno 2026, es. 1)
- Esercizio 3 · invariante su matrice a colonne decrescenti
- Esercizio 4 · ordinamento con scambi, traccia e invariante
- Esercizio 5 · Fibonacci ricorsivo, chiamate e complessità
- Esercizio 7 · dimostrazioni sulle foglie di un albero binario proprio
Teoria collegata
- Algoritmo di Strassen e ibridazione
- Esponenziazione veloce per quadrature successive
- Polinomi - rappresentazione per coefficienti e per valori e convoluzione
- Problemi computazionali - istanze, soluzioni, correttezza e complessità
- Prodotto di matrici - algoritmo iterativo e ricorsivo a blocchi
- Alberi
- Algoritmi ricorsivi
- Problemi computazionali e algoritmi