Trovare il peggior caso di tipo heap


8

Sto lavorando al problema H nel concorso ACM ICPC 2004–2005 in Europa nord-orientale .

Il problema è fondamentalmente quello di trovare il caso peggiore che produce un numero massimo di scambi nell'algoritmo (setacciare verso il basso) per costruire l'heap.

  • Input: il file di input contiene ( ).n1≤n≤50,000
  • Output: output dell'array contenente numeri interi diversi da a , in modo che sia un heap e quando lo si converte in un array ordinato, il numero totale di scambi nelle operazioni di setacciatura è massimo possibile.n1n

Input di esempio: 6
output corrispondente:6 5 3 2 4 1

E i risultati di base:

[2, 1]   
[3, 2, 1]   
[4, 3, 1, 2] 
[5, 4, 3, 2, 1] 
[6, 5, 3, 4, 1, 2]

2
stai praticamente chiedendo "perché il mio codice è così lento"? Penso che questa domanda sia troppo localizzata e comunque rientri meglio in Stack Overflow
— Ran G.

No, davvero, voglio trovare il caso peggiore per l'algoritmo heapsort. Ma il mio codice è un tentativo di capire questi casi.
— jonaprieto,

2
Se vuoi provare heapsort su tutti i possibili ordini di array, non sorprende che il tuo algoritmo sia estremamente lento: avrà un tempo di esecuzione almeno di , Che cresce più che in modo esponenziale. 10! è già 3,6 milioni. Staresti meglio con un'analisi teorica. (commento ripubblicato quando ho letto male l'inizio della tua domanda, quindi la seconda parte del mio commento non era valida)Ω(n!)
— Alex ten Brink,

Questo documento sembra essere rilevante. Io secondo Ran; si prega di modificare la domanda in modo che ponga la domanda senza boilerplate.
— Raffaello

Potrebbe essere utile .

Risposte:


4

Dato il caso peggiore per , possiamo costruire il caso peggiore per come segue: facciamo un 'ciclo di scambio' come segue: prendiamo , lo mettiamo in e scambiamo con l'elemento massimo dei suoi figli, che è o , che scambiamo di nuovo con l'elemento massimo dei suoi figli e così via, fino a quando lasciamo l' heap -element, a quel punto mettiamo l'ultimo elemento nella posizione .nn+1n+1a[0]a[0]a[1]a[2]nn+1

Un esempio: il caso peggiore per è . Sostituiamo 6 che crea l'heap , dopo di che finiamo con 2, che inseriamo alla fine: .n=5[5,4,3,2,1][6,5,3,4,1][6,5,3,4,1,2]

Il metodo sopra funziona per induzione: partiamo dal risultato peggiore per gli elementi ed eseguiamo un'operazione di set-down al contrario, massimizzando il numero di swap che deve fare ( swaps). Non puoi fare più swap di così, quindi massimizza il numero di swap dopo la prima operazione di estrazione-min, dopo di che ti rimane esattamente il caso peggiore per gli elementi per la successiva operazione di estrazione-min. Ciò implica che il numero di swap è effettivamente massimo.n−1⌊log⁡(n)⌋n−1

Si noti che questo metodo fornisce risultati diversi da quelli ottenuti:

[1]
[2, 1]
[3, 2, 1]
[4, 3, 1, 2]
[5, 4, 1, 3, 2]
[6, 5, 1, 4, 2, 3]
[7, 6, 1, 5, 2, 4, 3]
[8, 7, 1, 6, 2, 4, 3, 5]
[9, 8, 1, 7, 2, 4, 3, 6, 5]
[10, 9, 1, 8, 2, 4, 3, 7, 5 ,6]

Tuttavia, entrambe le soluzioni sono corrette:

[5, 4, 1, 3, 2]
[2, 4, 1, 3| 5]
[4, 2, 1, 3| 5]
[4, 3, 1, 2| 5]
[2, 3, 1| 4, 5]
[3, 2, 1| 4, 5]

[5, 4, 3, 2, 1]
[1, 4, 3, 2| 5]
[4, 1, 3, 2| 5]
[4, 2, 3, 1| 5]
[1, 2, 3| 4, 5]
[3, 2, 1| 4, 5]

[6, 5, 1, 4, 2, 3]
[3, 5, 1, 4, 2| 6]
[5, 3, 1, 4, 2| 6]
[5, 4, 1, 3, 2| 6]
[2, 4, 1, 3| 5, 6]
[4, 2, 1, 3| 5, 6]
[4, 3, 1, 2| 5, 6]
[2, 3, 1| 4, 5, 6]
[3, 2, 1| 4, 5, 6]

[6, 5, 3, 4, 1, 2]
[2, 5, 3, 4, 1| 6]
[5, 2, 3, 4, 1| 6]
[5, 4, 3, 2, 1| 6]
[1, 4, 3, 2| 5, 6]
[4, 1, 3, 2| 5, 6]
[4, 2, 3, 1| 5, 6]
[1, 2, 3| 4, 5, 6]
[3, 2, 1| 4, 5, 6]

Ma questi esempi non sono tanti!
— jonaprieto,
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.