Divisão e Conquista: Par de Pontos mais Próximo Fernando Lobo Algoritmos e Estrutura de Dados II 1 / 18 Divisão e Conquista (cont.) Problema: Dado um conjunto de pontos no plano, obter o par de pontos mais próximo. Input: P = {p 1, p 2,..., p n} com p i = (x i, y i). Output: Um par de pontos p i e p j cuja distância seja mínima. 2 / 18
É fácil fazer um algoritmo de complexidade Θ(n 2 ), basta calcular a distância entre cada par de pontos e escolher o par com a distância mínima. Vamos ver um algoritmo de complexidade Θ(n lg n) obtido com a técnica de divisão e conquista. 3 / 18 Aplicações Computação gráfica. Sistemas de informação geográfica. Controlo de tráfego aéreo. etc. 4 / 18
Alguma ideia? 5 / 18 Divisão Divide o conjunto P em dois conjuntos, Q e R, cada qual com n/2 pontos. A divisão é feita através de mediana da coordenada x. 6 / 18
Conquista Resolve recursivamente o problema para Q e R. Se o n. o de pontos for suficientemente pequeno (por exemplo n <= 3) calcula-se à força bruta entre cada par de pontos. 7 / 18 Combinar: a parte difícil Temos de o fazer em Θ(n) para obtermos uma complexidade total de Θ(n lg n). A distância mínima será o mínimo de três coisas: d Q, d R, d QR (distância mínima entre um ponto de Q e um ponto de R). 8 / 18
Combinar (cont.) Seja δ = min(d Q, d R ) Para sabermos se existe algum par de pontos p i e p j, tal que p i Q, p j R e dist(p i, p j) < δ, basta verificar os pontos que estão a uma distância máxima de δ da linha L. Chamemos a esse conjunto de pontos S. 9 / 18 Reparem que potencialmente, S poderá conter os n pontos iniciais. Ou seja, até aqui ainda não garantimos que não tenhamos de calcular as distâncias entre cada ponto de Q com cada ponto de R, o que daria Θ(n 2 ). 10 / 18
Não pode haver mais do que um ponto por caixa. Se houvesse, estariam do mesmo lado (ambos em Q ou ambos em R) e teriam uma distância inferior a δ = uma contradição. 11 / 18 Se s 1 e s 2 são elementos de S e dist(s 1, s 2) < δ, então s 1 e s 2 têm de estar no máximo a 11 posições um do outro na sequência S y (S ordenado por y). Porquê? Só pode haver um ponto por caixa. Logo, 12 posições ou mais em y implica a existência de pelo menos 2 linhas horizontais entre s 1 e s 2 = dist(s 1, s 2) > δ. 12 / 18
Não é necessário estar a ordenar S em cada chamada recursiva. Se o fizéssemos obteríamos a recorrência T (n) = 2T (n/2) + Θ(n lg n). Não dá para aplicar o Teorema Mestre. Mas pode-se provar que T (n) = Θ(n lg n lg n). O objectivo é obtermos a recorrência T (n) = 2T (n/2) + Θ(n). Ou seja, o passo Combinar tem de ser feito em Θ(n). 13 / 18 A ideia é pré-ordenar o array P pela coordenada x (obtendo o array P x) e pela coordenada y (obtendo o array P y ). Depois cada chamada recursiva recebe dois arrays de pontos (ordenados por x e por y). Closest-Pair(P, n) P x = P ordenado por x / Θ(n lg n) P y = P ordenado por y / Θ(n lg n) (p1, p2) = Closest-Pair-Rec(P x, P y, n) 14 / 18
Closest-Pair-Rec(P x, P y, n) if n 3 Calcula a distância entre cada par de pontos e retorna o par cuja distância é mínima. else // divide P em Q e R Constrói Q x, Q y, R x, R y / Θ(n) (q1, q2) = Closest-Pair-Rec(Q x, Q y, nq) (r1, r2) = Closest-Pair-Rec(R x, R y, nr) dq = dist(q1, q2) dr = dist(r1, r2) δ = min(dq, dr) x = coordenada x do último ponto do array Q x // linha L : x == x // S = pontos em P que estão a uma distância // máxima de δ de L. Constrói S y a partir de P y / Θ(n) 15 / 18 (continuação...) Para cada s S y, calcular a distância de s a cada um dos próximos 11 pontos em S y. Seja (s1, s2) o par que obtém a distância mínima. if dist(s1, s2) < δ return (s1, s2) elseif dq < dr return (q1, q2) else return (r1, r2) 16 / 18
Para uma implementação concreta ainda faltam alguns detalhes Como obter Q x, Q y, R x, R y em Θ(n)? A divisão do problema em dois subproblemas foi feita através da mediana da coordenada x. Será que funciona se houver pontos com a mesma coordenada x? É trabalho para vocês pensarem. 17 / 18 Notas adicionais Este algoritmo foi inventado em inícios dos anos 70 por Shamos e Hoey. O limite dos 11 pontos pode ser reduzido. O livro CLRS refere apenas a verificação de 7 pontos. Em 2011, José Luís Pereira (um colega vosso que estava a fazer AED-II tal e qual como vós) demonstrou que com algumas modificações ao algoritmo, basta apenas verificar 2 pontos. (os interessados podem ler http://arxiv.org/abs/1010.5908) 18 / 18