Esercizio 3invariante su matrice a colonne decrescenti
In questa pagina 6
Testo (esempio di tema d'esame, seconda parte, esercizio 1, 5 punti). Sia una matrice con valori interi, con la proprietà che i valori in ogni colonna sono ordinati in senso decrescente dalla riga alla riga . Il seguente algoritmo determina il massimo numero di valori in una colonna.
i <- 0; j <- 0
while (i < n) AND (j < m) do {
if (A[i,j] <= 0) then j <- j + 1
else i <- i + 1
}
return iTrovare un opportuno invariante per il ciclo, che serva per provare la correttezza dell'algoritmo (la prova di correttezza non è richiesta).
Richiami
Un invariante di ciclo vale prima del ciclo, si conserva a ogni iterazione e a fine ciclo implica la tesi (vedi Dimostrazioni, induzione e invariantiTecniche di dimostrazione (esempio, controesempio, assurdo), induzione con casi base multipli, invarianti di ciclo (inizializzazione, conservazione, uso alla fine), schema generale per provare la correttezza; esempi svolti su arrayMax, sequenza di bit e numeri di Fibonacci.Dimostrazioni, induzione e invarianti →).
Cosa fa l'algoritmo
Sia il numero di valori positivi della colonna . Poiché la colonna è decrescente, i valori positivi sono i primi della colonna (dalla riga ): se allora tutti i valori delle righe sono , e se allora lo sono tutti quelli delle righe . Si cerca .
L'algoritmo percorre la matrice a "scala": se la colonna ha al più valori positivi, quindi non può battere il valore già raggiunto e si passa alla colonna ; se la colonna ha almeno valori positivi e si prova ad arrivare a .
Invariante
All'inizio di ogni iterazione (e quindi a ogni controllo della condizione del while):
La (a) dice che le colonne già scartate non hanno più di valori positivi; la (b) che almeno una colonna ne ha o più (in particolare il valore è raggiungibile).
Verifica (pur senza richiedere la prova)
- Inizio: ; la (a) è vuota e la (b) è .
- Conservazione. Se si incrementa : la colonna ha , quindi la (a) vale anche per ( non cambia, quindi la (b) resta vera). Se si incrementa : la colonna ha , quindi e la (b) vale con il nuovo ; la (a) resta vera perché .
- Uscita: si esce con o con . Se , dalla (b) e poiché si ha . Se , dalla (a) ogni colonna ha e dalla (b) , quindi . In entrambi i casi , ed è ciò che restituisce l'algoritmo.
- Terminazione: a ogni iterazione cresce o , e è limitato da ; le iterazioni sono al più , quindi la complessità è (una colonna alla volta e una riga alla volta, mai all'indietro).
Esempio
, , colonne decrescenti:
Traccia : con ; ; ; ; ; : esce e restituisce . Ad ogni passo valgono (a) e (b): ad esempio a la colonna ha e . (L'invariante è stato controllato con matrici casuali.)
Errori comuni
- Un invariante tipo " è il numero di positivi nella colonna ": falso, non c'è una colonna fissata.
- Dimenticare la parte (b), cioè che il valore è effettivamente raggiunto da qualche colonna: senza di essa dall'uscita con si dedurrebbe solo .
- Dimenticare l'ipotesi di decrescenza: senza di essa non dice nulla sulle righe sotto.
Versione ripasso
Testo. matrice con colonne decrescenti dall'alto in basso; il ciclo while (i<n) AND (j<m): se allora altrimenti ; return i (massimo numero di valori in una colonna). Trovare un invariante.
- Fatto chiave: colonna decrescente ⇒ i positivi sono i primi ; ⇒ ; ⇒ .
- Invariante: (a) per ogni ; (b) (vedi Dimostrazioni, induzione e invariantiTecniche di dimostrazione (esempio, controesempio, assurdo), induzione con casi base multipli, invarianti di ciclo (inizializzazione, conservazione, uso alla fine), schema generale per provare la correttezza; esempi svolti su arrayMax, sequenza di bit e numeri di Fibonacci.Dimostrazioni, induzione e invarianti →).
- Conservazione: ++ quando (); ++ quando (, quindi ).
- Uscita: ⇒ ; ⇒ per (a) e per (b); quindi . Al più iterazioni.
- Esempio: , : traccia : , restituisce .
- Errori: invariante su una colonna fissa; (b) dimenticata; ipotesi di decrescenza non usata.