Алгоритм знаходження сукупної маси "бару Granola" - як структури?


19

Я дослідник планетарних наук, і над одним проектом, над яким я працюю, є моделювання кілець Сатурна в N- тілах. Мета цього конкретного дослідження - спостерігати за тим, як частинки збиваються під власною самогравітацією і вимірюють сукупну масу скупчень проти середньої швидкості всіх частинок у клітині. Ми намагаємося розібратися, чи це може пояснити деякі спостереження, зроблені космічним кораблем Кассіні під час сатурнівського літнього сонцестояння, коли великі споруди бачили, як вони кидали тіні на майже крайні кільця. Нижче наведено скріншот того, як виглядає будь-який даний часовий крок. (Кожна частинка має діаметр 2 м, а сама симуляційна комірка становить близько 700 м.)

_ N_-клітина тіла імітації кілець Сатурна з частинками, зображеними як крихітні затінені сфери на чорному тлі.

Код, який я використовую, вже виплюває середню швидкість на кожному кроці. Що мені потрібно зробити - це визначити спосіб визначення маси частинок в грудях, а НЕ збилися частинки між ними. Я знаю положення кожної частинки, масу, розмір тощо, але я не знаю легко, що, скажімо, частинки 30 000-40 000 разом із 102 000-105 000 складають одну ланцюжок, що для людського ока очевидно.

Отже, алгоритм, який мені потрібно написати, повинен бути кодом з якомога менше введених користувачем параметрів (для копіюваності та об'єктивності), який би пройшов усі позиції частинок, з'ясував, які частинки належать до скупчень, а потім обчислить маси. Було б чудово, якби це могло зробити це для "кожної" грудки / пасма на відміну від усього в клітині, але я не думаю, що мені насправді це потрібно, щоб розділити їх.

Єдине, про що я думав, - це зробити якийсь обчислення відстані N 2, де я обчислив би відстань між кожною частинкою, і якщо, скажімо, найближчі 100 частинок знаходилися на певній відстані, то ця частинка вважалася б частиною кластер. Але це здається досить неохайним, і я сподівався, що ви, люди та програмісти, можете знати більш елегантне рішення?


Відредаговано з моїм рішенням: Що я зробив, це скористатись підходом найближчого сусіда / кластера та спершу виконати швидку n-брудну реалізацію N 2 . Отже, візьміть кожну частинку, обчисліть відстань до всіх інших частинок, а поріг для кластера чи ні, чи було N частинок на відстані d відстані ( на жаль, два параметри, які потрібно встановити апріорі , але, як це сказали деякі відповіді / коментарі, я не збирався тікати, не маючи деяких із них).

Потім я проскочив це, не сортуючи відстані, а просто виконую замовлення на пошук N і збільшуючи лічильник частинок в межах d , а цей прискорював коефіцієнт на 6 разів. Потім я додав "дурне дерево програміста" (тому що я знаю майже нічого не стосується деревних кодів). Я поділяю комірку імітації на встановлену кількість сіток (найкращі результати, коли розмір сітки ≈7 д ), де основна сітка вирівнюється з коміркою, одна сітка зміщена вдвічі в x і y , а дві інші зміщені на 1/4 в ± х і ± у . Потім код ділить частинки на сітки, тоді кожна частинка N повинна мати лише відстані, обчислені до інших частинок цієї клітини.

Теоретично, якби це справжнє дерево, я повинен отримати порядок N * log ( N ) на відміну від швидкостей N 2 . Я потрапив десь між двома, де для підмножини на 50 000 частинок я отримав 17-кратне збільшення швидкості, а для клітини-частинки на 150 000 я отримав 38-кратну швидкість. 12 секунд для першої, 53 секунди для другої, 460 секунд для комірки з частинками 500 000 частин. Це порівнянна швидкість з тим, скільки часу потрібно коду, щоб запустити моделювання на 1 крок вперед, так що це розумно в даний момент. О, і це повністю потоком, тому знадобиться стільки процесорів, скільки я можу на нього кинути.


3
Я не особливо обізнаний з цієї тематики, тому можу надати собі невелику допомогу, але ви читали статтю Вікіпедії про аналіз кластеру ? Здається, це дуже активне поле вивчення.
Коул Кемпбелл

Я з обережністю ставлюся до кластерного коду, принаймні до чогось подібного до DBSCAN, тому що я думаю, що це «слідкує» за деякими тонкими нитками, про які я візуально знаю, не є частиною кластерів, але це може бути алгоритмічно. У мене є досвід роботи з кодами типу DBSCAN, оскільки я використовую це для своєї іншої роботи, вивчаючи кратери.
Стюарт Роббінс

1
Будь-який код, який ідентифікує такі пасма, майже напевно матиме певну настройку "чутливості".
Роберт Харві

2
Домовились. Справжня складність тут полягає в тому, що "скупчення" не є чітко визначеним терміном. Зрештою, вам доведеться розібратися з якимось алгоритмом аналізу кластерного аналізу (який, справді, вже запропоноване вами рішення), можливо, поєднаний з якимось проходом зниження шуму.
Коул Кемпбелл

2
це може допомогти, якщо ви намалюєте на своїй картинці те, що, на вашу думку, є дійсним згустком (і, можливо, недійсним)
jk.

Відповіді:


3

Моя перша пропозиція - розрізати свою проблему на дві проблеми: спочатку з’ясуйте, що ви хочете, а потім з’ясуйте, як ефективно отримати те, що ви хочете. Ви не можете ефективно отримати щось, чого ви ще не визначили. Я викладу у цій відповіді кілька ідей, які можуть допомогти вам знайти це визначення. Я пропоную вам зробити неефективну реалізацію ідей, які вам сподобалися спочатку, застосувати їх до кількох не надто великих наборів даних, оцінити результати вручну, адаптувати своє визначення та повторити (можливо, задайте інше запитання тут), поки ви не будете задоволені ваше визначення. Після цього я пропоную вам задати ще одне питання, як ефективно обчислити результат свого визначення (якщо вам все-таки потрібна допомога).

Отже, давайте подивимось, що відповідало б нашій інтуїтивній ідеї «пасма». Ваші пасма складаються з приблизно рівномірно розподілених точок, хоча ви повинні перевірити це, зробивши збільшене зображення (оригінального набору даних) - роздільна здатність вашої картини занадто низька, щоб з упевненістю сказати, що точки дійсно приблизно рівномірно розподілені . Я припускаю, що вони за цю відповідь.

Початковою ідеєю може бути погляд кожного найближчого сусіда. Виберемо точку X, назвемо її найближчу сусідку Y і встановимо D як відстань між X та Y. Далі подивимось на коло C навколо X з радіусом D * A, де A - параметр настройки, скажімо A = 3. Якщо X є частиною пасма, ми очікуємо, що для кожної точки Z в C відстань від Z до найближчого сусіда W приблизно таке ж, як D. Якщо він значно коротший, скажіть більше A (або, можливо, якийсь інший параметр B) тоді X, мабуть, поблизу від точок, які набагато ближче один до одного, ніж до X, тому X, ймовірно, не є частиною ланцюга.

Однак цей критерій не є повним. Він дає лише критерій виявлення "межі" між областями, щільними з точками, і ділянками, менш щільними з точками. Нам ще належить об’єднати точки разом у нитки.

На вашому малюнку є особливість, яка показує, що це не просто. У правому нижньому куті вашої фотографії розташована порівняно велика площа з безліччю бродячих точок. Самі ці бродячі точки приблизно розподіляються приблизно рівномірно, тому якщо ми маємо видалити всі точки навколо пасма навколо нього (та всі інші точки), то ми очікуємо, що будь-який алгоритм виявлення нитки мітить цей набір бродячих точок як нитку! Тому нам потрібно бути обережними при створенні наших кластерів.

Ідеєю може бути наступне. Ми будемо робити графік на цих точках, де вершинами є точки, а ребра означають, що дві точки мають однакову щільність. Для кожного пункту ми перевіряємо вищевказаний критерій. Якщо він перевіряється, ми з'єднуємо X з ребром до всіх точок у C. Якщо він не перевіряється, ми не додаємо жодного краю, і позначаємо X як "збита". Зробивши це для кожної точки, ми розглянемо набір підключених компонентів. Вони повинні складатися з одного (у випадку з вашим малюнком, але інші набори даних можуть мати декілька) з'єднаних компонентів, що складаються з усіх точок в нитках, плюс (можливо, багато) більше компонентів, що складаються з одиночних бродячих точок і цих «бродячих ниток». Однак на цих бродячих нитках є точки, позначені як "бродячі", тому ви можете просто ігнорувати будь-який компонент, що містить крапку, позначену як "бродячий".

Небезпека цієї ідеї полягає в тому, що у вас може з’явитися особливість, коли щільність пасма прогресивно знижується, коли ви рухаєтесь вздовж пасма, поки щільність не буде настільки низькою, що є лише набором заблукалих точок. Оскільки наш критерій "локальний", він може не виявити цього і позначити ці бродячі точки як частину пасма. Я не впевнений, що це буде проблемою: я б припустив, що більшість бродячих точок має сприймати критерій, оскільки зміни щільності на вашій картині здаються досить різкими.

Якщо ця проблема все-таки виникає, ви можете спробувати альтернативу просто взяти підключені компоненти. Для кожної точки X обчислюємо відстань до найближчого сусіда D (X). Ми починаємо з точки з мінімальним D (X) і виконуємо BFS (або DFS , порядок не має значення). Додамо будь-яку точку Y, D (Y) не набагато більша за D (X) (за допомогою регульованого коефіцієнта), з якої ми почали. Якщо ми стикаємося з точкою Y, яка має занадто великий D (Y), ми видаляємо край (X, Y), позначаємо Y як "бродячий" і діємо так, ніби ми ніколи не відвідували Y у нашій BFS. Якщо правильно налаштовано, це повинно запобігти проблемі, яку я описав вище.

Альтернативна ідея виправити цю проблему діє дещо локальніше: ви можете зробити BFS і відслідковувати найнижчий D (X) (я використовую D (X) як міру щільності навколо точки), що зустрічається щонайбільше скажімо 10 BFS-кроки раніше, і якщо ми стикаємося з Y, у якого D (Y) набагато більший, ніж цей D (X), ми робимо те саме, що й інше (потенційне) рішення, яке я запропонував.

Як застереження: всі ідеї, про які я говорив, я придумав лише зараз, я не знаю, чи вивчали цю конкретну проблему раніше, тому я можу просто проростити нісенітницю. Просто спробуйте ті ідеї (чи то мої, чи ваші власні), які вам здаються розумними, і з’ясуйте, чи справді вони працюють, і лише тоді зосередьтесь на їх ефективному втіленні.


2

За допомогою модульного розкладання ви можете створити дерево, яке буде містити всі частинки, оскільки листя і верхні вузли будуть кластеризувати їх. На основі цього дерева можна визначити заходи, які застосовуються до кожного його вузла від кореня до листя донизу. Ви зупиняєте цей обхід вниз, коли вимірювання досягають визначених користувачем порогів. Одним із таких вимірів може бути щільність опуклого корпусу всіх частинок у скупченні.


1

Я думаю, ти працюєш за алгоритмом кластеризації машинного навчання.

На цій сторінці з інструментарію Python SciKit Learn є зображення, які підказують, що алгоритм DBSCAN (Вікіпедія) може бути тим, що ви шукаєте. Це здається ідеальним, оскільки вхідним параметром є розмір сусідства, тоді як більшість інших алгоритмів кластеризації хочуть кількість кластерів, про які ви не знали б заздалегідь.

"Алгоритм на основі густини для виявлення кластерів у великих просторових базах даних з шумом" Естер, М., К. Крігель, Дж. Сандер та X. Сю, в матеріалах 2-ї Міжнародної конференції з виявлення знань та видобутку даних, Портленд, АБО , AAAI Press, С. 226–231. 1996 рік


0

Я думав над цією проблемою. Я не фахівець з фізики, тому поводьтеся зі мною.

Здається, що відстань між частинками не визначає скупчення. Це перекриття гравітаційних полів чи ні.

Візьміть частинку P і визначте, які інші частинки мають перекриваються гравітаційні поля.

Потім візьміть одну з таких і зробіть те ж саме. Ваша мета - не знайти всі частинки в грудці, а знайти її межі.

Повторіть це, поки не знайдуться всі скупчення.

Тепер поверніться назад і визначте масу скупчень. У вас будуть усунені бродячі частинки, і ви можете використовувати межі кускою, щоб знайти масу.

Я не впевнений, чи це допомагає, але це все, що я міг придумати.


Що таке гравітаційне поле ?
Девід Кауден

0

Ви можете в кінці кожного кроку часу перетворити дані в графік, обчислити мінімальну діапазон, а потім почати видаляти краї, що перевищують певний поріг. Це повинно дати вам грудки і простий спосіб перерахувати через частинки в кожній грудочці.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.