Algoritmo para encontrar a massa agregada de "barras de granola" - como estruturas?


19

Sou pesquisador de ciências planetárias e um projeto no qual estou trabalhando é a simulação de corpos em N dos anéis de Saturno. O objetivo deste estudo em particular é observar como as partículas se aglutinam sob sua própria gravidade e medir a massa agregada dos aglomerados versus a velocidade média de todas as partículas na célula. Estamos tentando descobrir se isso pode explicar algumas observações feitas pela sonda Cassini durante o solstício de verão de Saturno, quando grandes estruturas foram vistas projetando sombras nos anéis quase de ponta a ponta. Abaixo está uma captura de tela da aparência de qualquer timestep. (Cada partícula tem 2 m de diâmetro e a própria célula de simulação tem cerca de 700 m de diâmetro.)

Célula do corpo N de uma simulação dos anéis de Saturno com partículas mostradas como pequenas esferas sombreadas contra um fundo preto.

O código que estou usando já mostra a velocidade média a cada passo do tempo. O que eu preciso fazer é descobrir uma maneira de determinar a massa de partículas nos aglomerados e NÃO as partículas dispersas entre eles. Conheço a posição, massa, tamanho, etc. de cada partícula, mas não sei com facilidade que, digamos, as partículas 30.000 a 40.000, juntamente com 102.000 a 105.000, formam um filamento que, para o olho humano, é óbvio.

Portanto, o algoritmo que eu preciso escrever seria um código com o menor número possível de parâmetros inseridos pelo usuário (para replicabilidade e objetividade) que passaria por todas as posições das partículas, descobrisse quais partículas pertencem aos aglomerados e calcule o massa. Seria ótimo se isso pudesse ser feito para "cada" grupo / vertente, em oposição a tudo na célula, mas não acho que realmente precise separá-los.

A única coisa em que eu pensava era fazer algum tipo de cálculo de distância de N 2, onde eu calculava a distância entre cada partícula e se, digamos, as 100 partículas mais próximas estivessem dentro de uma certa distância, essa partícula seria considerada parte de um grupo. Mas isso parece muito desleixado e eu esperava que vocês, pessoal e programadores do CS, soubessem de uma solução mais elegante?


Editado com Minha solução: O que fiz foi adotar uma espécie de abordagem de vizinho / cluster mais próximo e fazer a implementação rápida e suja do N 2 primeiro. Portanto, pegue todas as partículas, calcule a distância de todas as outras partículas e o limite para um cluster ou não era se havia N partículas a uma distância d (dois parâmetros que precisam ser definidos a priori , infelizmente, mas como foi dito por alguns respostas / comentários, eu não iria me safar por não ter alguns deles).

Depois, apressei-o não classificando distâncias, mas simplesmente fazendo uma busca N de ordem e incrementando um contador para as partículas dentro de d , e isso acelerou o fator por um fator de 6. Em seguida, adicionei uma "árvore de programador estúpida" (porque eu sei quase nada sobre códigos de árvores). I dividir a célula em simulação de um determinado número de grelhas (melhores resultados quando o tamanho da grade ≈7 d ), onde as principais linhas de grade para cima com a célula, uma grade é compensado pela metade em x e y , e os outros dois são compensados pelos 1/4 in ± x e ± y . O código então divide as partículas nas grades, então cada partícula N só precisa ter distâncias calculadas para as outras partículas naquela célula.

Teoricamente, se essa fosse uma árvore real, eu deveria obter a ordem N * log ( N ) em oposição às velocidades N 2 . Eu cheguei em algum lugar entre os dois, onde para um subconjunto de 50.000 partículas, obtive um aumento de 17x na velocidade e, para uma célula de 150.000 partículas, obtive um aumento de 38x na velocidade. 12 segundos para o primeiro, 53 segundos para o segundo, 460 segundos para uma célula de 500.000 partículas. Essas são velocidades comparáveis ​​a quanto tempo o código leva para executar a simulação 1 passo a passo adiante, então é razoável neste momento. Ah - e é totalmente encadeado, portanto, serão necessários tantos processadores quanto eu puder.


3
Eu não sou particularmente familiarizado com esse assunto, então posso fornecer pouco em termos de assistência, mas você leu o artigo da Wikipedia sobre análise de cluster ? Parece ser um campo de estudo muito ativo.
Cole Campbell

Eu sou cauteloso em relação a um código de cluster, pelo menos algo como DBSCAN, porque acho que ele "seguiria" alguns dos fios finos que eu sei que visualmente não fazem parte de clusters, mas podem ser algoritmicamente. Eu tenho experiência com códigos do tipo DBSCAN, pois eu o uso em outros trabalhos, estudando crateras.
Stuart Robbins

1
Qualquer código que identifique fios como esse quase certamente viria com algum tipo de configuração de "sensibilidade".
21813 Robert Harvey

2
Acordado. A dificuldade real aqui é que "grupo" não é um termo bem definido. No final do dia, você terá que usar algum tipo de algoritmo de análise de cluster (que, na verdade, sua solução proposta já existe), talvez combinada com algum tipo de passe de redução de ruído.
Cole Campbell

2
pode ajudar se você desenhar na sua imagem o que você acha que é um grupo válido (e possivelmente inválido)
jk.

Respostas:


3

Minha primeira sugestão é dividir o seu problema em dois: primeiro, descubra o que você quer e depois descubra como conseguir o que deseja com eficiência. Você não pode obter com eficiência algo que ainda não definiu. Vou colocar algumas idéias nesta resposta que podem ajudá-lo a encontrar essa definição. Sugiro que você faça uma implementação ineficiente das idéias que você gosta primeiro, aplique-a em alguns conjuntos de dados não muito grandes, avalie os resultados manualmente, adapte sua definição e repita (possivelmente fazendo outra pergunta aqui), até que você esteja satisfeito com sua definição. Depois disso, sugiro que faça outra pergunta sobre como calcular com eficiência o resultado da sua definição (se você ainda precisar de ajuda).

Então, vamos ver o que corresponderia à nossa ideia intuitiva de um "fio". Seus fios parecem consistir em pontos aproximadamente uniformemente distribuídos, embora você deva verificar isso fazendo uma imagem ampliada (do conjunto de dados original) - a resolução da sua imagem é muito baixa para dizer com certeza que os pontos são realmente uniformemente distribuídos . Eu vou assumir que eles são para esta resposta.

Uma idéia inicial pode ser olhar para o vizinho mais próximo de cada ponto. Vamos escolher um ponto X, chamar seu vizinho mais próximo Y e definir D como a distância entre X e Y. Em seguida, olhamos para o círculo C em torno de X com raio D * A, onde A é um parâmetro de ajuste, digamos A = 3. Se X faz parte de uma cadeia, esperamos que, para cada ponto Z em C, a distância de Z ao vizinho mais próximo W seja aproximadamente a mesma que D. Se for significativamente menor, diga mais que A (ou talvez algum outro parâmetro B) então X aparentemente está próximo de pontos muito mais próximos um do outro do que X, então X provavelmente não faz parte de um fio.

Este critério não está completo no entanto. Ele fornece apenas um critério para detectar uma 'borda' entre áreas densas com pontos e áreas menos densas com pontos. Ainda precisamos agrupar pontos em fios.

Há um recurso na sua foto que mostra que isso não é simples. No canto inferior direito da sua foto, há uma área relativamente grande com muitos pontos dispersos. Esses pontos perdidos são eles mesmos uniformemente distribuídos; portanto, se removermos todos os pontos do cordão ao redor dele (e todos os outros pontos), esperamos que qualquer algoritmo de detecção de cordão marque esse conjunto de pontos perdidos como um cordão! Portanto, precisamos ter cuidado ao criar nossos clusters.

Uma idéia pode ser fazer o seguinte. Vamos fazer um gráfico sobre esses pontos, onde os vértices são os pontos e as arestas significam que dois pontos têm densidade semelhante. Para cada ponto, verificamos o critério acima. Se sair, conectamos X com uma aresta a todos os pontos em C. Se não sair, não adicionamos nenhuma aresta e marcamos X como 'perdido'. Depois de fazer isso para todos os pontos, consideramos o conjunto de componentes conectados. Eles devem consistir em um único componente (no caso da sua imagem, mas outros conjuntos de dados podem ter múltiplos) conectados, consistindo em todos os pontos dos fios, além de (potencialmente muito) mais componentes consistindo em pontos dispersos únicos e esses 'fios dispersos'. No entanto, esses fios perdidos possuem pontos que foram marcados como 'perdidos'; portanto, você pode simplesmente ignorar qualquer componente que contenha um ponto marcado como 'perdido'.

Um perigo dessa idéia é que você pode ter um recurso em que a densidade de um fio diminui progressivamente à medida que você se move ao longo do fio, até que a densidade seja tão baixa que seja apenas um conjunto de pontos dispersos. Como nosso critério é 'local', ele pode não detectar isso e marcar esses pontos perdidos como parte do fio. Não tenho certeza se isso será um problema: eu acho que a maioria dos pontos perdidos deve ser capturada pelo critério, pois as alterações na densidade parecem bastante abruptas na sua imagem.

Se esse problema ocorrer, você pode tentar uma alternativa para apenas pegar os componentes conectados. Para cada ponto X, calculamos a distância até o vizinho mais próximo D (X). Começamos no ponto com o mínimo de D (X) e executamos um BFS (ou DFS , o pedido não importa). Adicionamos qualquer ponto Y cujo D (Y) não seja muito maior que o D (X) (por um fator sintonizável) com o qual começamos. Se encontrarmos um ponto Y com D (Y) muito grande, removemos a borda (X, Y), marcamos Y como 'disperso' e agimos como se nunca tivéssemos visitado Y em nosso BFS. Se ajustado corretamente, isso deve evitar o problema descrito acima.

Uma idéia alternativa para corrigir esse problema atua um pouco mais local: você pode fazer um BFS e acompanhar o menor D (X) (eu uso D (X) como uma medida da densidade em torno de um ponto) encontrado no máximo, digamos 10 As etapas do BFS antes e, se encontrarmos um Y com D (Y) muito maior que esse D (X), faremos o mesmo que a outra (potencial) solução que ofereci.

Como uma exoneração de responsabilidade: todas as idéias acima que eu pensei no local agora, eu realmente não sei se esse problema em particular já foi estudado antes, então eu posso estar começando a disparar bobagens. Apenas experimente as idéias (sejam minhas ou as suas) que lhe parecem sensatas e descubra se elas realmente funcionam e só então se concentre em implementá-las com eficiência.


2

Usando a decomposição modular, você pode criar uma árvore que conterá todas as partículas, pois as folhas e os nós superiores os agruparão. Com base nessa árvore, você pode definir medidas que são aplicadas a todos os nós, da raiz às folhas para baixo. Você interrompe esse percurso descendente quando as medições atingem os limites definidos pelo usuário. Uma dessas medidas pode ser a densidade do casco convexo de todas as partículas em um cluster.


1

Acho que você está atrás de um algoritmo de agrupamento de aprendizado de máquina.

Esta página do kit de ferramentas Python SciKit Learn tem imagens que sugerem que o algoritmo DBSCAN (Wikipedia) pode ser o que você está procurando. Parece ideal, pois o parâmetro de entrada é o tamanho da vizinhança, enquanto a maioria dos outros algoritmos de cluster deseja o número de clusters, que você não conheceria antecipadamente.

"Um algoritmo baseado na densidade para a descoberta de clusters em grandes bancos de dados espaciais com ruído" Ester, M., HP Kriegel, J. Sander e X. Xu, Nos Anais da 2ª Conferência Internacional sobre Descoberta de Conhecimento e Mineração de Dados, Portland, OR , AAAI Press, pp. 226–231. 1996


0

Eu estive pensando sobre este problema. Eu não sou um especialista em física, então tenha paciência comigo.

Parece que não é a distância entre as partículas que conta para determinar os aglomerados. É se os campos de gravidade se sobrepõem ou não.

Pegue uma partícula P e determine quais outras partículas têm campos de gravidade sobrepostos.

Então pegue um deles e faça a mesma coisa. Seu objetivo não é encontrar todas as partículas no grupo, mas encontrar seus limites.

Repita isso até que todos os grupos sejam encontrados.

Agora volte e determine a massa dos aglomerados. Você terá eliminado partículas dispersas e poderá usar os limites da massa para encontrar a massa.

Não tenho certeza se isso ajuda, mas é tudo em que consigo pensar.


O que é um campo de gravidade ?
quer

0

Você pode, no final de cada etapa do tempo, converter os dados em um gráfico, computar a árvore de abrangência mínima e começar a remover arestas que excedem um determinado limite. Isso deve fornecer aglomerados e uma maneira fácil de enumerar as partículas em cada aglomerado.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.