Eu tenho uma solução que pode parecer um pouco complicada, mas deve ser mais eficiente do que a pesquisa de força bruta ingênua :O(n2)
- deixar que ser o eixo entre os centros de massa de e .A BvAB
- Classifique os pontos em e ao longo deste eixo em ordem decrescente e crescente, respectivamente, resultando nas seqüências , , ..., e , , ..., .B a 0 a 1 a n b 0 b 1 b nABa0a1anb0b1bn
O restante está em pseudocódigo para deixar mais claro:
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
Ou seja, ao pré-classificar os pontos ao longo de , é possível filtrar os pares que nunca estarão dentro de pois ao longo de sempre será.dvd v ≤ ″ b k - a j ″bk−ajv≤∥bk−aj∥
No pior caso, ainda é , mas se e estiverem bem separados, deve ser muito mais rápido que isso, mas não melhor que , que é necessário para a classificação.A B O ( n log n )O(n2)ABO(nlogn)
Atualizar
Esta solução não é de forma alguma tirada do chapéu. É um caso especial do que uso nas simulações de partículas para encontrar todos os pares de partículas que interagem com o bineamento espacial. Meu próprio trabalho explicando o problema mais geral está aqui .
Quanto à sugestão de usar um algoritmo de varredura de linha modificado, embora intuitivamente simples, não estou convencido de que isso esteja em quando conjuntos disjuntos são considerados. O mesmo vale para o algoritmo aleatório de Rabin.O(nlogn)
Parece não haver muita literatura lidando com o problema do par mais próximo em conjuntos disjuntos, mas descobri isso , que não reivindica ser inferior a , e isso , que não parece para fazer qualquer reclamação sobre qualquer coisa.O(n2)
O algoritmo acima pode ser visto como uma variante da varredura de avião sugerida no primeiro artigo (Shan, Zhang e Salzberg), mas, em vez de usar o eixo- e sem classificação, o eixo entre os conjuntos é usado e os conjuntos são percorridos em ordem decrescente / crescente.x