Inserimento efficiente nell'elenco mantenendo il numero minimo di inversioni


15

Assumi due elenchi di elementi comparabili: u e s. Sia INV (u) il numero di inversioni in u.

Sto cercando un algoritmo efficiente per inserire gli elementi di s in te con un aumento minimo di INV (u).

Fondamentalmente vorrei inserire oggetti in un elenco mantenendolo "il più ordinato possibile" mantenendo l'ordine del primo elenco.

Esempio:

u = [4,6,2,9,7]
INV(u) = 3 ((4, 2), (6, 2) and (9, 7)

s = [8,3,10]

one optimal solution u' = [3, 4, 6, 2, 8, 9, 7, 10]
INV(u') = 5 ((4, 2), (7, 2) and (9, 7) + (3,2), (8,7))

different optimal solution u' = [3, 4, 6, 2, 9, 7, 8, 10]
INV(u') = 5 ((4, 2), (7, 2) and (9, 7) + (3,2), (9,8))

Come puoi vedere, non esiste una soluzione ottimale unica.

Sarei felice per qualsiasi tipo di idea o direzione da esaminare.


Spunti di riflessione: l'approccio ingenuo sarebbe: prendere un elemento da s, confrontarlo con ciascun elemento in u da sinistra a destra, incrementare se si tratta di un'inversione e riportare il numero precedentemente calcolato. Quindi attraversare l'elenco da destra a sinistra con lo stesso elemento, aumentando i conteggi per ciascuna posizione. Funziona in O (| s | * | u |) con spazio = O (| u |)
trevore

1
Ispezionare tutte le sottosequenze aumentanti massime può portare da qualche parte.
Raffaello

Risposte:


2

Questa è un'elaborazione sulla risposta di Trevore. È troppo lungo per inserire un commento e contiene le prove della sua soluzione (o almeno come la capisco).

Puoi mostrare che in qualsiasi soluzione ottimale, gli elementi di appariranno ordinati. sIn caso contrario, assumere e compaiono in ordine inverso in una soluzione ottimale. Sia σ 1 il numero di elementi tra s 1 e s 2 che sono minori di s 1 e β 1 è il numero di quelli che sono più grandi di s 1 . Definire σ 2 e β 2 in modo simile per s 2 . Si noti che σ 1s1<s2σ1s1s2s1β1s1σ2β2s2 e β 2σ1σ2 . Scambiando s 1 e s 2 cambierà il numero di inversioni di - β 1 + β 2 - σ 2β2β1s1s2 che è al massimo -1.β1+β2σ2+σ11

Non è difficile vedere che gli elementi di possono essere inseriti in modo indipendente. sPoiché sembrano ordinati, gli elementi di non "sentono" la presenza reciproca. Cioè, coppie di elementi da sss non contribuiscono al conteggio delle inversioni. Per fare ciò, inserisci la mediana di modo ottimale in tempo lineare. Quindi, ricorsivamente, inserisci elementi di s inferiori alla mediana a sinistra della mediana e elementi più grandi della mediana alla sua destra.ss

Lascia che la mediana sia inserita nella posizione , il tempo di esecuzione di questo soddisfa, T ( | s | , | u | ) = T ( | s | / 2 , | u | - k ) + T ( | s | / 2 , k ) + | u | + | s | , il lineare | s |kT(|s|,|u|)=T(|s|/2,|u|k)+T(|s|/2,k)+|u|+|s||s|il fattore è trovare la mediana e mescolare gli elementi di | s | ) .s. È facile dimostrare per induzione che T(|s|,|u|)=O(|s|log|s|+|u|log|s|)

Si noti che la dipendenza da qui è ottimale. Poiché la risoluzione del problema con u vuota è equivalente all'ordinamento di s utilizzando solo confronti. La dipendenza da | u | è anche ottimale, poiché il problema per un elenco singleton s|s|us|u|s ed una lista deve richiedere lavoro lineare.u


Grazie per l'elaborazione. Questa è esattamente la soluzione che intendevo dire.
trevore,

1

Ok, ecco la mia soluzione:

Un'osservazione (che ho più o meno dimostrato) è che una soluzione ottimale sarà sempre quella in cui s è ordinato in modo crescente. Questo dà origine ad un algoritmo O ((| u | + | s |) * log (| s |)).

Per trovare la soluzione ottimale per un singolo elemento, fai come ho detto nel mio commento: Prendi un elemento da s, confrontalo con ciascun elemento in u da sinistra a destra, incrementa un contatore è un'inversione e porta il numero precedentemente calcolato. Quindi attraversare l'elenco da destra a sinistra con lo stesso elemento, aumentando i conteggi per ciascuna posizione.

Questo è O (| u |).

Ordina s.

Per l'elemento centrale di s nella posizione m: trova la posizione migliore b in u (usando il metodo dall'alto).

Dividi s a meu b e chiama ricorsivamente con le parti sinistra e destra, concatenando i risultati con m nell'ordine giusto.

Fermati non appena sei vuoto.


Non lo capisco s è un input. Non puoi presumere che s sia in ordine. L'algoritmo deve funzionare per tutti i possibili valori di s.
DW

Sì, ma in qualsiasi soluzione ottimale gli elementi di s finiranno sempre per essere ordinati in modo crescente nel nuovo array. Nota il passaggio "Ordina s". Vedi l'esempio sopra. Quello che ho dimostrato finora è che: per a, b in s, a <b se a è posizionato in modo ottimale in u, il posto ottimale per b è alla destra di a.
trevore,
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.