Ho una soluzione che può sembrare un po 'contorta, ma dovrebbe essere più efficiente della ricerca ingenua :O(n2)
- lascia sia l'asse tra i centri di massa di e .A BvAB
- Ordinare i punti in e lungo questo asse rispettivamente in ordine decrescente e crescente, risultando nelle sequenze , , ..., e , , ..., .B a 0 a 1 a n b 0 b 1 b nABa0a1anb0b1bn
Il resto è in pseudo-codice per renderlo più chiaro:
d = infinity.
for j from 1 to n
if (b_1 - a_j) along v > d then break endif
for k from 1 to n
if (b_k - a_j) along v > d then
break
else
d = min( d , ||b_k - a_j|| )
endif
enddo
enddo
Cioè, preordinando i punti lungo , puoi filtrare le coppie che non saranno mai entro una dall'altra poiché lungo sarà sempre.vdbk−ajv≤∥bk−aj∥
Nel caso peggiore questo è ancora , ma se e sono ben separati, dovrebbe essere molto più veloce di quello, ma non migliore di , che è richiesto per l'ordinamento.O(n2)ABO(nlogn)
Aggiornare
Questa soluzione non è affatto estratta da un cappello. È un caso speciale di ciò che uso nelle simulazioni di particelle per trovare tutte le coppie interagenti di particelle con binning spaziale. Il mio lavoro che spiega il problema più generale è qui .
Per quanto riguarda il suggerimento di utilizzare un algoritmo di cambio linea modificato, sebbene intuitivamente semplice, non sono convinto che questo sia in quando si considerano insiemi disgiunti. Lo stesso vale per l'algoritmo randomizzato di Rabin.O(nlogn)
Non sembra esserci molta letteratura che affronti il problema della coppia più vicina in insiemi disgiunti, ma ho trovato questo , che non pretende di essere sotto , e questo , che non sembra per fare affermazioni su qualsiasi cosa.O(n2)
L'algoritmo sopra può essere visto come una variante della scansione del piano suggerita nel primo documento (Shan, Zhang e Salzberg), tuttavia invece di utilizzare l' asse e nessun ordinamento, viene utilizzato l'asse tra i set e gli insiemi vengono attraversati in ordine decrescente / crescente.x