Warmup: bitvector casuali
Come warm-up, possiamo iniziare dal caso in cui ogni bitvector viene scelto in modo uniforme a caso. Quindi si scopre che il problema può essere risolto in tempo (più precisamente, può essere sostituito con ).1,6 lg 3O ( n1.6min ( k , lgn ) )1.6lg3
Prenderemo in considerazione la seguente variante in due serie del problema:
Insiemi trovati di bitvectors, determinare dove esiste senza sovrapposizione pair . s ∈ S , t ∈ TS, T⊆ { 0 , 1 }Ks ∈ S, t ∈ T
La tecnica di base per risolvere questo problema è dividere e conquistare. Ecco un algoritmo che usa divide-and-conquer:O ( n1.6k )
Dividi e base alla posizione del primo bit. In altre parole, forma , , , .T S 0 = { s ∈ S : s 0 = 0 } S 1 = { s ∈ S : s 0 = 1 } T 0 = { t ∈ T : t 0 = 0 } T 1 = { t ∈ T : t 0 = 1 }STS0= { s ∈ S: s0= 0 }S1= { s ∈ S: s0= 1 }T0= { t ∈ T: t0= 0 }T1= { t ∈ T: t0= 1 }
Ora ricorsivamente cercare una coppia non sovrapposta da , da e da . Se una chiamata ricorsiva trova una coppia non sovrapposta, emettila in uscita, altrimenti produce "Non esiste una coppia sovrapposta".S 0 , T 1 T 1 , S 0S0, T0S0, T1T1, S0
Poiché tutti i bitvector sono scelti a caso, possiamo aspettarci e . Pertanto, abbiamo tre chiamate ricorsive e abbiamo ridotto la dimensione del problema di un fattore due (entrambe le serie sono ridotte di un fattore due). Dopo la divisione di , uno dei due set scende alla dimensione 1 e il problema può essere risolto in tempo lineare. Otteniamo una relazione di ricorrenza lungo le linee di , la cui soluzione è . Considerando il tempo di esecuzione in modo più preciso nel caso di due set, vediamo che il tempo di esecuzione è .| T b | ≈ | T | / 2 lg min ( | S | , | T | ) T ( n ) = 3 T ( n / 2 ) + O ( n k ) T ( n ) = O ( n 1.6 k ) O| SB| ≈ | S| / 2| TB| ≈|T| / 2lgmin ( |S| , |T| )T( n ) =3T( n / 2 ) + O ( n k )T( n ) = O ( n1.6k )O ( min ( |S| , |T| )0.6max(|S|,|T|)k)
Questo può essere ulteriormente migliorato, osservando che se , la probabilità che esista una coppia non sovrapposta è esponenzialmente piccola. In particolare, se sono due vettori casuali, la probabilità che non si sovrappongano è . Se , ci sono tali coppie, quindi per un limite di unione, la probabilità che esista una coppia non sovrapposta è al massimo . Quando , questo è . Quindi, come fase di pre-elaborazione, sex , y ( 3 / 4 ) k | S | = | T | = N n 2 n 2 ( 3 / 4 ) k k ≥ 2.5 lg n + 100 ≤ 1 / 2 100 k ≥ 2.5 lg n + 100k≥2.5lgn+100x,y(3/4)k| S| = | T| =nn2n2(3/4)kk≥2.5lgn+100≤1/2100k≥2.5lgn+100, quindi possiamo immediatamente restituire "Non esiste alcuna coppia non sovrapposta" (la probabilità che ciò non sia corretto è trascurabilmente piccola), altrimenti eseguiamo l'algoritmo sopra.
In questo modo otteniamo un tempo di esecuzione di (o per la variante a due set proposta sopra), per il caso speciale in cui i bitvector vengono scelti in modo uniforme a caso.O ( min ( | S | , | T | ) 0,6 max ( | S | , | T | ) min ( k , lg n ) )O(n1.6min(k,lgn))O(min(|S|,|T|)0.6max(|S|,|T|)min(k,lgn))
Naturalmente, questa non è un'analisi del caso peggiore. I bitvector casuali sono notevolmente più facili del caso peggiore, ma trattiamolo come un riscaldamento, per avere alcune idee che forse possiamo applicare al caso generale.
Lezioni dal riscaldamento
Possiamo imparare alcune lezioni dal riscaldamento sopra. In primo luogo, dividere e conquistare (dividere in una piccola posizione) sembra utile. In secondo luogo, si desidera dividere in una posizione bit con il maggior numero di in quella posizione possibile; più ci sono, minore è la riduzione della dimensione del sottoproblema.010
In terzo luogo, ciò suggerisce che il problema si aggrava man mano che la densità di diminuisce - se ci sono pochissimi tra i bitvector (sono principalmente ), il problema sembra piuttosto difficile, poiché ogni divisione si riduce la dimensione dei sottoproblemi un po '. Quindi, definire la densità come la frazione di bit che sono (cioè, tra tutti i bit ) e la densità della posizione dei bit per essere la frazione di bitvector che sono nella posizione .1 0 Δ 1 n k i 1 i110Δ1nki1i
Gestione di una densità molto bassa
Come passo successivo, potremmo chiederci cosa succede se la densità è estremamente piccola. Si scopre che se la densità in ogni posizione di bit è inferiore a , ci viene garantito che esiste una coppia non sovrapposta: esiste un argomento di esistenza (non costruttiva) che mostra che alcuni non sovrapposti la coppia deve esistere. Questo non ci aiuta a trovarlo, ma almeno sappiamo che esiste.1/k−−√
Perché è così? Diciamo che una coppia di bitvector è coperta dalla posizione bit se . Si noti che ogni coppia di bitvector sovrapposti deve essere coperta da una posizione di bit. Ora, se fissiamo una particolare posizione di bit , il numero di coppie che possono essere coperte da quella posizione di bit è al massimo . Sommando tutte le delle posizioni dei bit, troviamo che il numero totale di coppie coperte da una certa posizione dei bit èi x i = y i = 1 i ( n Δ ( i ) ) 2 < n 2 / k k < n 2x,yixi=yi=1i(nΔ(i))2<n2/kk<n2. Ciò significa che deve esistere una coppia che non è coperta da alcuna posizione di bit, il che implica che questa coppia non si sovrappone. Quindi se la densità è sufficientemente bassa in ogni posizione di bit, allora sicuramente esiste una coppia non sovrapposta.
Tuttavia, non riesco a identificare un algoritmo veloce per trovare una coppia così non sovrapposta, in questi regimi, anche se ne è garantito uno. Non vedo immediatamente alcuna tecnica che produrrebbe un tempo di esecuzione che ha una dipendenza sub-quadratica da . Quindi, questo è un bel caso speciale su cui concentrarsi, se vuoi passare un po 'di tempo a pensare a questo problema.n
Verso un algoritmo del caso generale
Nel caso generale, un euristico naturale sembra essere: scegliere la posizione del bit con il maggior numero di (ovvero, con la più alta densità) e dividerlo. In altre parole:1i1
Trova un po 'la posizione che massimizza .Δ ( i )iΔ(i)
Dividi e base alla posizione dei bit . In altre parole, forma , , , .T i S 0 = { s ∈ S : s i = 0 } S 1 = { s ∈ S : s i = 1 } T 0 = { t ∈ T : t i = 0 } T 1 = { t ∈ T : t i = 1 }STiS0={s∈S:si=0}S1={s∈S:si=1}T0={t∈T:ti=0}T1={t∈T:ti=1}
Ora ricorsivamente cercare una coppia non sovrapposta da , da e da . Se una chiamata ricorsiva trova una coppia non sovrapposta, emettila in uscita, altrimenti produce "Non esiste una coppia sovrapposta".S 0 , T 1 T 1 , S 0S0,T0S0,T1T1,S0
La sfida è analizzare le sue prestazioni nel peggiore dei casi.
Supponiamo che come fase di pre-elaborazione calcoliamo prima la densità di ogni posizione di bit. Inoltre, se per ogni , supponiamo che la fase di pre-elaborazione produca "Esiste una coppia sovrapposta" (mi rendo conto che questo non mostra un esempio di coppia sovrapposta, ma mettiamolo da parte come una sfida separata). Tutto ciò può essere fatto in tempo. Le informazioni sulla densità possono essere gestite in modo efficiente mentre eseguiamo chiamate ricorsive; non sarà il contributo dominante al tempo di esecuzione. iO(nk)Δ(i)<1/k−−√iO(nk)
Quale sarà il tempo di esecuzione di questa procedura? Non ne sono sicuro, ma qui ci sono alcune osservazioni che potrebbero aiutare. Ogni livello di ricorsione riduce la dimensione del problema di circa bitvector (ad esempio, da bitvector a bitvector). Pertanto, la ricorsione può raggiungere solo livelli di . Tuttavia, non sono immediatamente sicuro di come contare il numero di foglie nell'albero di ricorsione (ci sono molte meno di foglie), quindi non sono sicuro del tempo di esecuzione che dovrebbe portare per. nn-n/ √n/k−−√n √n−n/k−−√ 3 √k−−√3k√