Esempi di algoritmi e prove che sembrano corretti, ma non lo sono


15

Nella mia introduzione al corso di programmazione, stiamo imparando il metodo di inizializzazione-manutenzione-terminazione per dimostrare che un algoritmo fa quello che ci aspettiamo. Ma abbiamo solo dovuto dimostrare che un algoritmo già noto per essere corretto, è corretto. Non ci è mai stato chiesto di dimostrare che un algoritmo non è corretto.

Esistono esempi classici di algoritmi che sembrano corretti, ma non lo sono? Sto cercando casi in cui l'approccio Initialization-Maintenance-Termination cattura qualcosa che l'intuizione a prima vista non lo fa.


5
Forse di interesse: cs.stackexchange.com/q/29475/755
DW

5
Voto perché penso che questa sia una domanda pedagogica molto importante. È leggermente fuori portata per cstheory, ma non conosco una piattaforma migliore per questo, e ci sono molti istruttori di algoritmi nella comunità cstheory. La maggior parte dei corsi di progettazione di algoritmi espone gli studenti solo a correggere algoritmi esistenti e a problemi facilmente risolvibili con tecniche note. Ciò rafforza l'impressione, così attraente per gli studenti, che ci si può fidare in sicurezza della propria sensazione intuitiva che un algoritmo apparentemente plausibile sia giusto. Un buon corso di progettazione di algoritmi dovrebbe fare il contrario!
Neal Young,

3
Mi piacerebbe avere una collezione come questa.
Chandra Chekuri,

Risposte:


20

Massimo locale 2D

input: matrice bidimensionale An×nUN

output: un massimo locale - una coppia tale che A [ i , j ] non abbia una cella vicina nell'array che contiene un valore strettamente maggiore. (io,j)UN[io,j]

(Le celle vicine sono quelle tra che sono presenti nell'array.) Quindi, per esempio, se A lo èUN[io,j+1],UN[io,j-1],UN[io-1,j],UN[io+1,j]UN

0134323125014013

quindi ogni cella in grassetto è un massimo locale. Ogni array non vuoto ha almeno un massimo locale.

Algoritmo. Esiste un algoritmo -time: basta controllare ogni cella. Ecco un'idea per un algoritmo più veloce e ricorsivo.O(n2)

Dato , definisci la croce X in modo che sia composta dalle celle nella colonna centrale e dalle celle nella riga centrale. Prima controlla ogni cella X per vedere se la cella è un massimo locale in A . In tal caso, restituire una cella del genere. Altrimenti, sia ( i , j ) una cella in X con il valore massimo. Da ( i , jUNXXUN(io,j)X non è un massimo locale, deve avere una cella vicina ( i , j ) con un valore maggiore.(io,j)(io',j')

Partizione (l'array A , meno le celle in X ) in quattro quadranti - i quadranti in alto a sinistra, in alto a destra, in basso a sinistra e in basso a destra - in modo naturale. La cella vicina (UNXUNX con valore maggiore deve trovarsi in uno di quei quadranti. Chiama quel quadrante A . (io',j')UN'

Lemma. Quadrant contiene un massimo locale di A .UN'UN

Prova. Considera di iniziare dalla cella . Se non è un massimo locale, passare a un vicino con un valore maggiore. Questo può essere ripetuto fino ad arrivare a una cella che è un massimo locale. Quella cella finale deve essere in A , perché A è delimitata su tutti i lati da celle i cui valori sono inferiori al valore di cella ( i , j ) . Questo dimostra il lemma. (io',j')UN'UN'(io',j')

L'algoritmo si chiama ricorsivamente sul sotto-arrayn2×n2 per trovare un massimo locale ( i , j ) lì, quindi restituisce quella cella.UN'(io,j)

Il tempo di esecuzione per una matrice n × n soddisfa T ( n ) = T ( n / 2 ) + O ( n ) , quindiT(n)n×nT(n)=T(n/2)+O(n) . T(n)=O(n)

Pertanto, abbiamo dimostrato il seguente teorema:

Teorema. Esiste un algoritmo -time per trovare un massimo locale in un array n × n .O(n)n×n

O abbiamo?


In prima lettura, l'unico errore che ho notato è stata la soluzione di ricorrenza. È l'unico errore?
Radu GRIGore,

1
La ricorrenza è corretta. L'algoritmo no!
Neal Young,

1
Ah, sì, ho fatto un errore stupido con la ricorrenza. Vedo il problema: il massimo che dimostri esiste non è (necessariamente) quello che trovi. E quello che trovi ignora la X.
Radu GRIGore

3
Ecco un esempio:
(2143300101230001023002222222333233300323000032300)
Radu GRIGore

2
UN'UN
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.