A união de hedge é sempre tão rápida quanto dividir e conquistar?

8

Adams descreve um algoritmo de dividir e conquistar para encontrar a união de dois conjuntos (representados como árvores de pesquisa binária com ponderação de peso). Ele então descreve um novo algoritmo de "união de hedge" que, segundo ele, melhora o algoritmo de dividir e conquistar. No entanto, ele não oferece uma prova, ou mesmo uma explicação real, de por que deveria ser , e muito menos por que deveria ser mais rápido do que dividir e conquistar.O(m+n)

Blelloch, Ferizovic e Sun mostram que o algoritmo de dividir e conquistar de Adams, na verdade, atinge o idealmente teoricamente ideal que . No entanto, eles não abordam o algoritmo de hedge union.Θ(mregistro(n/m+1))mn

A união de hedge é, de fato, tão eficiente quanto dividir e conquistar? A parte menos óbvia é a guarnição interna. Parece, pelo menos superficialmente, duplicar o trabalho entre as subárvores esquerda e direita que a divisão completa compartilha entre elas. Talvez esteja tudo bem por algum motivo, mas não sei por quê.

Uma investigação adicional: Haskell Data.Sete Data.Mapusa variantes de hedge de interseção e diferença, além de união. Não encontrei nenhuma discussão publicada sobre esses algoritmos. Perguntas semelhantes se aplicam a elas também.

dfeuer
fonte

Respostas:

3

Embora eu ainda tenha que ver ou produzir uma análise teórica dos algoritmos de hedge, tenho algumas evidências empíricas de que eles são piores que os algoritmos de dividir e conquistar para árvores binárias.

Começando com o código no containerspacote Haskell , otimizei o algoritmo de hedge union aplicando manualmente a especialização de padrão de chamada para reduzir a alocação intermediária. Isso melhorou seu desempenho em cerca de 10%, dando uma chance justa.

Começando com o código de dividir e conquistar em Adams, otimizei o algoritmo de união adicionando casos especiais quando uma das entradas é um singleton (o código da união de hedge otimiza um lado, portanto, e não está claro se o outro lado pode ser otimizado similarmente).

Testei cada implementação usando uma coleção de benchmarks de operação de conjunto fornecidos containers. Dividir e conquistar era geralmente mais rápido que o hedge, às vezes duas vezes mais rápido. Quando era mais lento, era apenas um pouco.

Benchmarks semelhantes de outras operações de conjunto deram resultados semelhantes.


Especulação:

Os algoritmos de hedge podem ser úteis ao usar árvores com grandes fatores de ramificação, que podem ser mais caros para dividir recursivamente. Eles também podem ser úteis para pequenas subárvores, onde podem economizar alocação suficiente para valer o trabalho extra.

dfeuer
fonte
Você realmente mudou a implementação com Data.Setbase nessas observações?
Joachim Breitner
@JoachimBreitner, sim, eu fiz. Também usei a mesma abordagem para os novos utilitários de mesclagem segura, embora caracterizar suas características precisas de desempenho seja certamente muito difícil de se preocupar.
Dfeuer