Complessità nell'applicazione di una permutazione sul posto


27

Con mia sorpresa, non sono stato in grado di trovare documenti su questo - probabilmente ho cercato le parole chiave sbagliate.

Quindi, abbiamo una matrice di qualsiasi cosa e una funzione sui suoi indici; è una permutazione.ff

Come riordinare l'array secondo con memoria e runtime il più vicino possibile a e ?fO(1)O(n)

Ci sono condizioni aggiuntive quando questa attività diventa più semplice? Ad esempio, quando sappiamo esplicitamente che una funzione è l'inverso di ?gf

Conosco un algoritmo che segue i cicli e attraversa un ciclo per ogni indice per verificare se è il minimo nel suo ciclo, ma ancora una volta ha il tempo di esecuzione peggiore dei casi , anche se in media sembra comportarsi meglio ...O(n2)


Un'osservazione semplice: se non solo l'array degli elementi ma anche l'array contenente la funzione f è scrivibile, è facile eseguire l'attività in tempo O (n) usando i registri interi O (1) (ciascuno della lunghezza O ( log n) bit) e spazio aggiuntivo per un elemento semplicemente seguendo ciascun ciclo. Ma questo non funziona se la funzione f è data su una memoria di sola lettura (o f è data solo come un oracolo), che penso sia un presupposto in questa domanda.
Tsuyoshi Ito,

23
Fich et al. 1995 : tempo, spazio. Discute anche alcuni casi speciali. O(nlogn)O(logn)
Jukka Suomela,

Sì, presumo che abbiamo f come oracolo.
jkff,

3
@JukkaSuomela, dovresti trasformarlo in una risposta. Inoltre, considerando che è una permutazione arbitraria, un semplice argomento entropico produce spazio e / o tempo, quindi sarei sorpreso se potessi fare meglio di nel tempo e nello spazio . fO(nlogn)O(nlogn)
user834

Risposte:


4

Opzione 0: Permuting In Place (1995) di Faith E. Fich, J. Ian Munro, Patricio V. Poblete tempo spazio.O(nlogn)O(log2n)

Opzione 1: imbrogliare comprimendo la tua permutazione in una struttura di dati sintetica, vedi Munro http://www.itu.dk/people/ssrao/icalp03-a.pdf .

Opzione 2: utilizzare una decomposizione del ciclo primo per memorizzare il perm in modo succinto e utilizzare quello spazio extra per imbrogliare http://oeis.org/A186202

Opzione 3: tenere traccia dell'indice più grande di ciascun ciclo manipolato. Per ogni iterazione usa il più grande indice invisibile per spostare tutto nel suo ciclo di uno. Se colpisce un indice visto annulla tutto ciò che funziona perché il ciclo è già stato manipolato. tempo, spazio.O(n2)O(#cycleslogn)

Opzione 4: tenere traccia dell'indice più grande di ciascun ciclo manipolato, ma solo in lotti di lunghezze di ciclo distinte. Per ogni iterazione usa il più grande indice invisibile per spostare tutto nel suo ciclo di uno. Se colpisce un indice visto annulla tutto ciò che funziona perché il ciclo è già stato manipolato. tempo, spazio.O(n2distinct_cycle_lengths)O((#cycles_with_same_size)logn)

Opzione 5: dallo stesso articolo di Munro dell'opzione 0, per ruotare il ciclo di se è l'indice più grande in quel ciclo. tempo e spazio.p ( i ) i O ( n 2 ) O ( log n )i=1..np(i)iO(n2)O(logn)


i metodi di compressione potrebbero non risparmiare spazio in generale: lo spazio peggiore per memorizzare una permutazione è . 3, 4 e 5 sembrano in generale cattivi come la soluzione OP già conosce o la soluzione di Fich, Munro e Poblete. E questa soluzione è già stata segnalata da @Jukkanlogn
Nikolov il

# 5 utilizza meno spazio di # 0 per un fattore log (n).
Chad Brewbaker,

1

Se si utilizza la rappresentazione ciclica della permutazione, è necessario 1 elemento array aggiuntivo per memorizzare l'elemento attualmente permutato e si possono eseguire i cicli in operazioni O (N) peggiori.


2
jkff ha già detto di conoscere l'algoritmo che segue il ciclo, quindi chiaramente vuole che la permutazione stessa sia trattata come (vicino a) una scatola nera. Come sottolinea la domanda, la conversione da una (quasi) scatola nera a una rappresentazione ciclica potrebbe richiedere tempo O (n ^ 2).
Joshua Grochow,

La scatola nera p (i) va bene. Fai semplicemente il giro del ciclo fino a quando non torni da me. Il problema è uno della complessità di Kolomogorov per memorizzare l'elenco di elementi che sono stati aggiornati in modo da non ciclicarli più volte. Munro ha dei limiti. itu.dk/people/ssrao/icalp03-a.pdf
Chad Brewbaker

-2

Qualsiasi permutazione di N articoli può essere convertita in qualsiasi altra permutazione usando N-1 o meno scambi. Il caso peggiore per questo metodo può richiedere chiamate O (n ^ 2) al tuo oracolo, F (). Inizia dalla posizione minima. Lascia che x sia la posizione che stiamo attualmente scambiando.

Se F (x)> = x, scambia le posizioni xe F (x). Altrimenti, dobbiamo trovare dove l'elemento che era in posizione F (x) è attualmente nell'elenco. Possiamo farlo con la seguente iterazione. Sia y = F (x). Fai fino a quando y> = x: y = F (y): Termina. Ora scambia le posizioni xey.


3
OP ha già detto di saperlo fare in tempo . O(n2)
Jukka Suomela,

Scusate. Sono nuovo di questo gruppo. Mi piace questo metodo per la sua semplicità. A volte trovo la semplicità più veloce dell'efficienza. Conosco un altro metodo che richiede O (n) passaggi, ma O (nlogn) spazio.
Russell Easterly,

1
Russell, anche allocando e azzerando lo spazio O (n log n) è già O (n log n), intendevi nella direzione opposta?
jkff,

Non hai davvero spazio e zero spazio. L'idea di base è quando F (x)> x dobbiamo ricordare dove mettiamo l'oggetto in posizione x. Per n davvero grandi, utilizzerei un database e terrei un registro di dove viene spostato l'elemento x. Il record potrebbe essere eliminato quando x arriva alla sua posizione finale.
Russell Easterly,

1
Ma allora perché stai dicendo che richiede O (n log n) spazio?
jkff,

-2

Questo metodo utilizza l'inverso di F e richiede n bit di memoria. Se x è la posizione di un elemento nella matrice originale, sia G (x) la posizione della voce nella matrice ordinata. Sia B un array a n bit. Impostare tutti i n bit di B su 0.

FOR x = 1 a n-1: IF B (x) == 0 THEN: y = G (x): DO UNTIL x == y: scambia le posizioni xey: B (y) = 1: y = G ( y): LOOP: ENDIF: NEXT X

Questo metodo continua a scambiare l'oggetto attualmente in posizione x con la posizione finale dell'articolo. Il ciclo interno termina quando l'elemento corretto viene scambiato nella posizione x. Poiché ogni scambio sposta almeno un oggetto nella posizione finale dell'oggetto, il ciclo Do interno non può eccedere più di n-1 volte durante la corsa. Penso che questo metodo sia O (n) tempo e spazio.


2
Hai guardato il giornale? I due algoritmi che elenchi qui sono i due "ovvi". Il documento ha quelli meno ovvi con diversi compromessi spazio-tempo, in particolare molto meno spazio.
Yuval Filmus,
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.