Cercare di comprendere questa prova di correttezza di Quicksort


10

Questa dimostrazione è una dimostrazione per induzione ed è la seguente:

P (n) è l'affermazione che "Quicksort ordina correttamente ogni array di input di lunghezza n."

Caso di base: ogni array di input di lunghezza 1 è già ordinato (P (1) contiene)

Fase induttiva: correzione n => 2. Correzione di alcuni array di input di lunghezza n.

È necessario mostrare: se P (k) vale per tutto k <n, anche P (n) vale

Quindi disegna un array A partizionato attorno a un perno p. Quindi disegna p e chiama la parte dell'array che è <p come prima parte, e la parte che è> p è la seconda parte. La lunghezza della parte 1 = k1 e la lunghezza della parte 2 è k2. Dalla prova di correttezza della subroutine di partizione (dimostrata in precedenza), il perno p si snoda nella posizione corretta.

inserisci qui la descrizione dell'immagine

Per ipotesi induttiva: 1a, 2a parte vengono ordinate correttamente per chiamate ricorsive. (Uso di P (K1), P (k2))

Quindi: dopo le chiamate ricorsive, l'intero array viene ordinato correttamente.

QED

La mia confusione : ho molti problemi nel vedere esattamente come questo ne dimostri la correttezza. Quindi supponiamo che P (k) valga davvero per tutti i numeri naturali k <n.

La maggior parte delle prove di induzione che avevo visto finora va qualcosa del genere: prova il caso base e mostra che P (n) => P (n + 1). Di solito comportavano anche una sorta di manipolazione algebrica. Questa dimostrazione sembra molto diversa e non capisco come applicare il concetto di induzione ad esso. Posso in qualche modo pensare che la chiave sia la correttezza del sottoprogramma Partition. Quindi il ragionamento per la sua correttezza è il seguente: Sappiamo che ogni chiamata ricorsiva, partizionerà l'array attorno a un perno. Questo perno sarà quindi nella sua giusta posizione. Quindi ciascun subarray verrà ulteriormente suddiviso attorno a un perno e quel perno sarà quindi nella sua posizione corretta. Questo va avanti e avanti fino a quando non si ottiene un subarray di lunghezza 1, che è ordinatamente banale.

Ma poi non assumiamo che P (k) valga per tutto k <n .... stiamo effettivamente MOSTRANDO lo fa (dal momento che la subroutine Partition posizionerà sempre un elemento nella sua posizione legittima). Non stiamo assumendo che P (k) vale per tutto k


Che cos'è "QUE"? Intendevi "QED"? (il latino Quod Erat Demonstrandum che non contiene alcuna parola che inizia per U )
Bakuriu,

1
Intendevo davvero QED. Immagino che la mia confusione mi abbia portato a scrivere "COSA?" in spagnolo
FrostyStraw,

Risposte:


13

Assumiamo infatti che valido per tutte le . Questa è una generalizzazione dello stile di prova "Da , dimostriamo " che conosci.P(k)k<nP(n1)P(n)

La prova che descrivi è conosciuta come il principio della forte induzione matematica e ha la forma

Supponiamo che sia un predicato definito su . Se possiamo dimostrarloP(n)n{1,2,}

  1. P(1) è vero e

  2. (k<n[P(k)])P(n)

Quindi è vero per tutti gli interi .P(n)n1

Nella prova a cui ti riferisci, è esattamente quello che sta succedendo. Per usare quicksort per ordinare un array di dimensioni , lo partizioniamo in tre pezzi: il primo sottoarray , il perno (che sarà nella sua posizione corretta) e il sottoarray rimanente di dimensioni . A proposito della partizione, ogni elemento nel primo sottoarray sarà minore o uguale al pivot e ogni elemento nell'altro sottoarray sarà maggiore o uguale al pivot, quindi quando ordiniamo ricorsivamente il primo e l'ultimo sottoarray, noi finirà per aver ordinato l'intero array.nknk1

Dimostriamo che questo è corretto per induzione forte: poiché il primo sottoarray ha elementi, possiamo indurre per induzione che sarà ordinato correttamente. Poiché il secondo sottoarray ha elementi, possiamo supporre che verrà ordinato correttamente. Quindi, unendo tutti i pezzi, finiremo per aver ordinato la matrice.k<nnk1<n


2
La parte interessante del principio della forte induzione è che il case base non è necessario! Se prendiamo nella fase di induzione, allora l'antecedente è vacuo, quindi abbiamo incondizionatamente. P(1)n=1k<1,P(k)P(1)
Mario Carneiro,

Va bene quindi ... per essere chiari ... ASSUMIAMO P (k) sia vero per tutti i k <n. E il modo in cui MOSTRIAMO che P (k) ==> P (n) (per tutto k <n) è attraverso la combinazione di sapere che il perno sarà sicuramente nella sua posizione corretta, e attraverso l'assunzione (l'ipotesi induttiva ) che anche i sottoarchi sinistro e destro sono ordinati. Combinalo con il caso base (in cui k = 1 <n) e la prova è completa?
FrostyStraw,

beh, suppongo che non basterebbe sapere che il perno è nella sua posizione corretta, ma anche che il sottoarray destro è tutto più grande del perno e quello sinistro è tutto meno di
FrostyStraw

@FrostyStraw Sono sussurri cinesi.
Raffaello

1
@FrostyStraw Hehe, intendevo la strategia di prova. :)
Raffaello

7

Questa dimostrazione utilizza il principio dell'induzione completa :

Supporre che:

  • Custodia base:P(1)
  • Step: Per ogni , se trattengono ( ipotesi di induzione ), allora vale anche .n>1P(1),,P(n1)P(n)

Quindi vale per tutto .P(n)n1

Puoi provare questo principio usando il solito principio di induzione considerando la proprietà I lasciati i dettagli.

Q(m)P(1) and P(2) and  and P(m)

Ora, usiamo l'induzione completa per dimostrare che la seguente versione di Quicksort ordina correttamente i suoi input:

Quicksort(A, n)
    if n = 1 then:
        return
    else:
        let X[1...x] consist of all elements of A[2],...,A[n] which are at most A[1]
        let Y[1...y] consist of all elements of A[2],...,A[n] which are larger than A[1]
        call Quicksort(X, x)
        call Quicksort(Y, y)
        set A to the concatenation of X, A[1], Y

Ecco A[1],...,A[n]la matrice di input, ed nè la sua lunghezza. L'affermazione che vogliamo dimostrare è la seguente:

Sia un array di lunghezza . Indichiamo il contenuto di dopo aver chiamato Quicksort da . Poi:n 1 A BAn1AB

  1. Quicksort termina su .A
  2. Esiste una permutazione di tale che .π1,,πn1,,nB[i]=A[πi]
  3. B[1]B[2]B[n] .

Proverò solo la terza proprietà, lasciando il resto a te. Lasciamo quindi che sia la seguente affermazione:P(n)

Se è un array di lunghezza e è il suo contenuto dopo l'esecuzione , allora .An1BQuicksort(A, n)B[1]B[2]B[n]

La prova è per induzione completa su . Se allora non c'è nulla da dimostrare, quindi supponiamo che . Sia come nella procedura . Poiché , l'ipotesi di induzione mostra che Inoltre, dal modo in cui abbiamo formato le matrici e , segue che . Quindi Segue immediatamente che . Quindi vale .nn=1n>1X,x,Y,yQuicksortx,y<n

X[1]X[2]X[x]Y[1]Y[2]Y[y]
XYX[x]A[1]<Y[1]
X[1]X[x]A[1]<Y[1]Y[y].
P ( n )B[1]B[n]P(n)

4

La parte mancante dell'argomento è la transitività di '<' - ovvero la proprietà che se a <b e b <c, quindi a <c. La prova che l'array finale è ordinato va in questo modo:

Sia A [i], A [j] elementi della matrice post-ordinamento, dove i <j. Quindi A [i] <A [j] segue uno dei seguenti casi di collocamento (e non ci sono altri casi):

(a) i e j sono nella prima partizione - A [i] <A [j] seguito da ricorsione / induzione.

(b) i e j sono nella seconda partizione - A [i] <A [j] seguito da ricorsione / induzione.

(c) i è nella prima partizione e j è l'indice del perno - A [i] <A [j] segue la prova della procedura di partizione.

(c) i è l'indice del pivot e j è nella seconda partizione - A [i] <A [j] segue la prova della procedura di partizione.

(e) i è nella prima partizione e j è nella seconda partizione, quindi per procedura di partizione, A [i] <pivot e pivot <A [j]. Quindi per transitività, A [i] <A [j].

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.