2012-04-12 19 views
7

Sto cercando il modo più veloce per decidere se un punto su una linea è o meno all'interno di un sottoinsieme di questa linea. mi viene data un punto intero, e ho anche una "lista" di entrambi:Come trovare se un punto si trova all'interno di un set di intervalli?

  1. Punti, rappresentata da un numero intero (3, 10, 1000, ecc)
  2. intervalli, che rappresento da 2 interi (2:10 è tutti i numeri interi da 2 a 10 inclusi.Possono, 50:60, ecc)

in questo esempio, se il valore del mio punto è 5, allora torno vero perché è incluso in un intervallo , lo stesso per 55. Se il mio punto è uguale a 1000, restituisco anche true perché corrisponde all'elenco di punti.

Sto cercando un modo veloce (più veloce di lineare) per verificare questa condizione, SENZA dover instanciare il numero intero come molti punti possibili (ad esempio, per un intervallo di 1: 1000 non desidero instanciare 1000 interi). Questo può essere fatto in un tempo logaritmico?

Grazie

edit: si può considerare che qualsiasi tempo necessario per pre-processo l'elenco dei dati è uguale a 0, perché una volta che i miei intervalli iniziali vengono elaborati ho bisogno di applicare questo test per 10k punti

+0

gli intervalli possono sovrapporsi? Non so se questo è importante, ma sembra che dovrebbe. – Almo

+0

potrebbero, ma posso pre-elaborare i miei dati in modo che non lo facciano più, il che non rappresenta un problema in termini di tempo perché sto usando gli stessi intervalli per elaborare i 10k punti – lezebulon

+0

Sono ordinati? – Freddy

risposta

0

Prima verifica una hash_map di punti. Questo è il semplice controllo.

Quindi, basta ordinare una mappa di intervalli dalla prima coordinata e quindi trovare il limite inferiore del punto.

Quindi controllare se si è contenuti nell'elemento restituito. Se non ci sei, non ci sei.

+1

Sembra che ci siano delle ipotesi in alcune delle risposte che gli intervalli potrebbero sovrapporsi. Hai il controllo della struttura dati che utilizzi per risolvere questo problema - non ha alcuna dipendenza necessaria all'esterno o l'intervallo iniziale impostato. Quindi non dovresti memorizzare intervalli di sovrapposizione in generale - unisciti a loro quando li inserisci nella mappa. Ogni volta che si tratta di intervalli questo è abbastanza standard. – ex0du5

4

Se gli intervalli di numeri interi sono ordinati e gli intervalli non si sovrappongono, è possibile eseguire la ricerca binaria per trovare l'intervallo corretto in tempo logaritmico.

Ci sono dei limiti sull'intervallo? In base a ciò, è probabile che tu possa trovare una funzione di hashing per la ricerca in un tempo costante. Ma questo dipende da come sono i tuoi vincoli.

+0

Penso di poter supporre che l'intervallo sia compreso tra 0 e 10 milioni. – lezebulon

+2

Se alcuni intervalli si sovrappongono, è possibile ordinarli e comprimere quelli sovrapposti in un unico intervallo. –

0

Si potrebbe fare in tempo sublimatico DATO una struttura dati dell'albero (mi raccomando un albero B), se non si conta il tempo impiegato per costruire l'albero (la maggior parte degli alberi prende n log n o tempo simile costruire).

Se si dispone solo di un elenco semplice, non si può fare meglio di lineare perché nel caso peggiore è necessario controllare tutti i punti e gli intervalli.

0

è possibile utilizzare un Bloom Filter per testare un punto e vedere se è non in un intervallo, in tempo lineare O (1). Se supera quel test, devi utilizzare un altro metodo come una ricerca binaria per vedere se è definitivamente parte di un intervallo, in O (log n) tempo.

+0

L'idea di hash ogni punto nell'intervallo? – mavam

+0

@MatthiasVallentin, sì lo è. La dimensione del filtro Bloom dipende dal numero di punti impostati e dalla probabilità di falsi positivi, non dal possibile intervallo di input. –

+0

Grazie, ho capito la tua idea ora. Tuttavia, ci sono molte scelte che i parametri del filtro Bloom devono risolvere inizialmente. Poiché questa struttura di dati viene spesso utilizzata in ambienti con vincoli di spazio, un approccio comune è quello di assumere una dimensione fissa e impostare la cardinalità per ricavare il valore ottimale di * k *, il numero di funzioni hash. Potresti chiarire cosa intendi per "taglia"? Una volta istanziato, la dimensione del filtro Bloom (di base) in genere non cambia più. – mavam

1

Dopo riflessione, penso che il seguente codice dovrebbe funzionare in tempo logaritmico, escluso il tempo necessario per costruire la mappa:

enum pointType { 
    point, 
    open, 
    close 
}; 
std::map<long int, pointType> mapPoints; 

mapPoints.insert(std::pair<long int, pointType>(3, point)); 

//create the 5:10 interval: 
mapPoints.insert(std::pair<long int, pointType>(5, open)); 
mapPoints.insert(std::pair<long int, pointType>(10, close)); 

int number = 4; 
bool inside = false; 
std::map<long int, pointType>::iterator it1 = mapPoints.lower_bound(number); 

if(it1->first == number || it1->second == close) { 
    inside = true; 
} 

Penso che questo dovrebbe funzionare fino a quando la mappa è riempito correttamente con non - intervalli di sovrapposizione

Problemi correlati