Come usare un algoritmo avido per trovare la sequenza non decrescente più vicina a quella data?


20

a1,,an0laibi0lbib i O ( n 4 max(|a1b1|,,|anbn|)biO(nl4)

Onestamente non ho idea di come iniziare a risolvere questa domanda. Mi sembra una domanda di programmazione dinamica, ma il professore ha detto che questo dovrebbe essere risolto usando un algoritmo avido. Sarebbe molto apprezzato se qualcuno potesse indicarmi la giusta direzione dando un piccolo suggerimento.

Risposte:


9

Cominciamo con la seguente osservazione:

Lascia che denoti il ​​massimo della sequenza , e indica il minimo. Se , scegliere è ottimale.un 1 , . . . , a n m i n a 1 = m a x b 1 = b 2 = . . . = b n = ( m a x + m i n ) / 2 maxa1,...,anmina1=maxb1=b2=...=bn=(max+min)/2

Perché è così? Bene, poiché la sequenza inizia con il massimo, o scegliamo grande e subiamo una grande deviazione dal minimo della sequenza (poiché ogni successivo deve essere maggiore o uguale a ), oppure scegliamo piccolo e soffriamo del deviazione a . La media minimizza la deviazione massima.b i b 1 b 1 m a xb1bib1b1max

Ora possiamo provare a generalizzare questa osservazione da usare sulle sequenze generali . Ad esempio, possiamo suddividere qualsiasi sequenza in sottosequenze, in modo che ciascuna inizi con il massimo della rispettiva sottosequenza.a1,...,an

Esempio: è suddiviso in , e .( 2 ) ( 6 , 4 , 1 , 5 , 2 ) ( 8 , 7 , 5 , 1 )(2,6,4,1,5,2,8,7,5,1)(2)(6,4,1,5,2)(8,7,5,1)

Dato questo partizionamento, ora possiamo risolvere ciascuna di queste sottosequenze separatamente e ottenere un'assegnazione di , che tuttavia potrebbe violare la condizione non decrescente. Questo può essere risolto senza perdere l'ottimalità.bi

Osserva che l'ultima sottosequenza contiene sempre il massimo dell'intera sequenza (altrimenti, ci sarebbe un'altra sottosequenza successiva). Sia i valori che abbiamo assegnato alle . Ora, per raggiungere la non decrescita in , partiamo da dietro a e ci verso il fronte. Se è maggiore di , impostiamo semplicemente . Se è più piccolo, lo manteniamo. Quindi, procediamo con il confronto di con e così via. Nota che abbassando qualsiasi al valore diw 1 , w 2 , . . . , W k k w 1 , . . . , w k w k w k - 1 w k w k - 1 : = w k w k - 2 w k - 1 w i w i + 1 w i w i + 1maxw1,w2,...,wkkw1,...,wkwkwk1wkwk1:=wkwk2wk1wiowi+1non aumenta mai la deviazione, poiché il valore massimo nella sottosequenza assegnata con è sempre inferiore al massimo nella assegnata con .wiowi+1

Questo algoritmo dovrebbe essere corretto, credo. Per quanto riguarda il tempo di esecuzione, il passaggio chiave è calcolare i massimi crescenti per le sottosequenze, che è possibile in ? Non sono sicuro di dove contribuisca.lO(n)l


2

Ho intenzione di pensare ad alta voce qui solo lavorando attraverso i suggerimenti che hai dato. Andiamo per il suggerimento originale di dire che è ciò che si dovrebbe provare per primo. Mi viene in mente un algoritmo goloso che ha quel tempo.O(nl)

La parte della complessità temporale significa che è possibile mantenere un elenco del conteggio di ciascuna occorrenza di ciascun valore 0 .. l . Quello, è solo creare un set Count = C 0 , , C l che tiene traccia del conteggio di ogni l nel set. È possibile creare l'elenco initalize scansionando una volta la sequenza di input.l0..lCount=C0,,Cll

È possibile eseguire la scansione di questo elenco in per ottenere il valore massimo e minimo. Se dovessi riempire l'intero elenco di b con questo punto medio, la tua varianza sarebbe semplicemente la differenza tra questo valore e il massimo / minimo. Questo è fondamentalmente lo scenario peggiore, chiamiamolo b w .O(l)bbw

Quindi il tuo lavoro al da sinistra. Puoi eliminare questo elemento dal conteggio e ottenere il minimo / massimo di b [ i + 1 ] ... b [ n ] in O ( l ) . Ora possiamo essere avidi. Noi non scegliamo b i > b w dato che le forze del restante intero elenco (per soddisfare il requisito di non-decrescente) e quindi aumenta la varianza. Il valore minimo che possiamo scegliere è b [ i - 1 ] . Se un ibiCountb[i+1]b[n]O(l)bi>bwb[i1]aiè nell'intervallo accettabile lo selezioniamo, se al di sotto dell'intervallo utilizziamo il minimo. Ciò minimizza la varianza a dati i vincoli conosciuti.bi

Questa è solo un'idea, forse sono fortunato e ti indica la giusta direzione. Questo algoritmo potrebbe non funzionare (funziona per i miei pochi semplici test), ma corrisponde ai suggerimenti forniti, quindi forse è utile. Se corretto, è facile vedere che la parte può sicuramente essere rilasciata su O ( log l ) , circa ancora di più, non sono sicuro.O(l)O(logl)


2

Ecco la soluzione del professore, che lui chiama "riduzione": per ogni da 0 a 1 , prova a costruire una soluzione se sappiamo che la deviazione è minore o uguale a i . Il primo i per cui è possibile trovare una soluzione è la deviazione minima. Possiamo trovare una soluzione data la deviazione in O ( n ) tempo. Quindi il tempo di esecuzione è O ( n l ) . Quindi, invece di utilizzare la ricerca lineare, possiamo usare la ricerca binaria per determinare la minima deviazione per la quale è possibile una soluzione. Ciò riduce il tempo di funzionamento a O ( n log li0liiO(n)O(nl) , che soddisfa il requisito di O ( n 4 O(nlogl).O(nl4)


4
Quindi la stato un trucco ... Ma sono più incuriosito dal "Siamo in grado di trovare una soluzione data la deviazione nel tempo O (n)" .. comemai nonè questala parte interessante? O(nl4)
jmad

Dato @jmad , per ogni j , prendo b j quale valore minimo che è almeno grande quanto tutti i precedenti b k , e che non è più dei lontano da una j . Se non riusciamo a trovare un valore del genere, cosa significa? Ciò significa che una precedente b t è più che i grandi di un j . Quindi un precedente a t è più di 2 i più grande di un j . Quindi quel valore di me non era possibile. Se passi attraverso il nijbjbkiajbtiajat2iajinvalori senza rimanere bloccati in questo modo, hai trovato una soluzione per senza backtracking, nel tempo O ( n ) . iO(n)
jwg,

O (n log l) sarebbe stato un forte suggerimento che è necessario eseguire una ricerca binaria nell'intervallo da 0 a l.
gnasher729,

0

Penso che questo dovrebbe essere fattibile in O (n).

Prendi il problema simile: dato , 1 ≤ i ≤ n e d ≥ 0, trova b i in ordine non decrescente in modo tale che | a i - b i | d per tutti i, oppure mostra che non è possibile. Questo può essere fatto in O (n), e usando la ricerca binaria il problema originale è risolto in O (n log l).aibi|aibi|d

Ora se ci sono i ≤ j tale che a_i - a_j> 2d, allora non c'è soluzione (perché ).biaid,bjaj+d<ai2d+d=aidbi

Ma se a_i - a_j ≤ 2d per tutti i ≤ j, penso che si troverà sempre una soluzione. Quindi tutto ciò che dobbiamo fare è trovare m = max (a_i - a_j) per tutti i ≤ j e scegliere d = floor ((m + 1) / 2). Quel massimo può essere trovato in O (n).


Idea intrigante! Posso credere che qualcosa del genere possa funzionare, ma sembra che ci sia un grande vuoto alla fine della tua risposta e sto facendo fatica a riempire i dettagli. Hai una prova che se per tutti i j allora esiste sempre una soluzione? Ancora più importante, come lo troviamo? La domanda iniziale dice che dobbiamo trovare la b i 's. Anche se supponiamo che esista una soluzione, ho difficoltà a vedere come trovare i b i corrispondenti . Puoi approfondire questo? aiaj2dijbibi
DW
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.