Estou em busca de um algoritmo de agrupamento espacial incremental . Aqui está o meu caso de uso:
- os usuários criam entradas com uma posição inicial
- os usuários podem alterar as posições das entradas existentes
Agora eu quero implementar um serviço dissociado que forneça informações de cluster desses dados. O serviço será notificado sempre que uma nova entrada for adicionada ou uma entrada existente for movida. O que é um bom algoritmo de clustering, portanto? Idealmente, ele deve escalar até grandes quantidades de dados e, se houver uma troca entre a qualidade do cluster e a complexidade do tempo de execução, eu concordo com resultados degradantes e, eventualmente, resultados consistentes (resultados obsoletos por algum tempo).
Para resumir meus requisitos:
- agrupamento espacial com base em posições
- modificações incrementais nas mudanças
- adicionar novas posições
- alterar posições existentes
- bom desempenho em tempo de execução
Desde já, obrigado!
algorithm
clustering
b_erb
fonte
fonte
Respostas:
O objetivo desse agrupamento é simplificar a exibição dos símbolos de pontos: quando muitos estiverem próximos no mapa, eles serão substituídos por um único símbolo para indicar um grupo.
Os requisitos apontam para a necessidade de uma solução simples e adaptável : os símbolos dos pontos podem ser atualizados e, à medida que o usuário aproxima o zoom, símbolos diferentes aparecerão em diferentes locais na extensão do mapa (ou tela).
Um excelente candidato é claramente um quadtree da região .
Existe um método mais simples que funcionará como um quadtree da região. Requer menos codificação, nenhuma criação antecipada de uma estrutura de dados, mas você paga um preço (pequeno) por precisar realizar alguns cálculos dinâmicos durante o zoom e o panorama. Apenas faça uma grade do mapa . Especificamente, suponha que n símbolos de ponto sejam desenhados na extensão atual do mapa, que possua um comprimento de dx e uma altura de dy . Em relação à origem do mapa, os símbolos precisam ser desenhados nas coordenadas ( x [i] , y [i] ), i = 1, 2, ..., n . A seleção de um tamanho de célula de grade de c particiona o mapa em uma grade de células. A célula na qual o local (x , y ) pertence está na linha j ( y ) = Piso [ y / c ] e coluna j ( x ) (contando de 0, com linhas indo de baixo para cima e colunas da esquerda para a direita). Você pode considerar qualquer célula que recebe dois ou mais pontos como um "cluster". O símbolo do cluster pode ser desenhado no centro da célula, que possui coordenadas ( j + c / 2, k + c / 2).
Isso leva à seguinte solução, apresentada no pseudocódigo:
Claramente, a carga computacional do algoritmo é O (número de pontos) no tempo e O (dx * dy / c ^ 2) no armazenamento. Os trade-offs envolvidos na seleção do tamanho da célula c são:
c deve ser o maior possível: o armazenamento é inversamente proporcional a c ^ 2: valores pequenos de c significam grandes quantidades de RAM. (O armazenamento pode ser reduzido para O (número de pontos) usando matrizes ou dicionários esparsos.)
c deve ser o maior possível: dois símbolos (pontos ou aglomerados) nunca estarão mais próximos que c / 2.
c deve ser o menor possível: todo símbolo de cluster representa locais a não mais que c / sqrt (2) dele.
c deve ser o menor possível: valores grandes de c tendem a criar muitos clusters e permitem que poucos pontos individuais apareçam.
Vamos fazer uma análise rápida de (4). Como ponto de partida, suponha que os locais a serem mapeados ocorram uniformemente aleatoriamente e independentemente um do outro. O número de células é N ( c ) = (Piso ( dx / c ) +1) * (Piso ( dy / c ) +1), que - pelo menos para valores maiores de c - é diretamente proporcional a c ^ 2) A distribuição das contagens de células seguirá aproximadamente uma lei de Poisson com intensidade lambda = n / N ( c ) = n * c ^ 2 / ( dx * dy) O número esperado de clusters é igual a
e ( c ) = n (1 - exp (- lambda ) (1 + lambda )).
Isso fica menor à medida que o lambda diminui para 0; isto é, à medida que o tamanho da célula c fica cada vez menor. O ponto desta análise é que a fórmula anterior permite prever quantos clusters podem existir, para que você possa selecionar um valor inicial de c para o qual e ( c ) esteja abaixo de um valor aceitável (enquanto ainda é grande o suficiente para limitar a RAM) requisitos). Não existe uma solução de forma fechada, mas algumas etapas de Newton-Raphson convergirão para uma rapidamente.
Essa abordagem é tão dinâmica - é rápida o suficiente para que a grade e o agrupamento conseqüente possam ser computados com cada zoom e pan e não requer estruturas de dados pré-computadas - que as "modificações incrementais" desejadas à medida que os dados são atualizados acontecem automaticamente.
fonte
Você está procurando algo como http://dev.openlayers.org/releases/OpenLayers-2.10/examples/strategy-cluster-threshold.html ? Nesse caso, o código não deve ser muito difícil de seguir.
fonte