27.06 Поиск двойных/тройных звездных систем
Ошибка.
Попробуйте повторить позже
Астроном решил исследовать звёздное небо в далёкой галактике, проведя кластеризацию звёзд по их расположению на
карте. Кластер звёзд — это набор точек на графике, каждая из которых находится от хотя бы одной
другой точки на расстоянии не более условных единиц. Каждая звезда принадлежит только одному
кластеру.
Двойная система — это два объекта на расстоянии менее , при этом других звёзд на расстоянии менее
у них
быть не должно.
Расстояние между двумя точками и
на плоскости вычисляется по формуле:
Аномалиями называют точки, находящиеся на расстоянии более одной условной единицы от точек кластеров. Аномалии в расчётах учитывать не нужно.
В файле A хранятся данные о звёздах двух кластеров, где ,
для каждого кластера. В каждой
строке записаны координаты одной звезды и её масса (в солнечных массах):
,
,
. Если масса
положительная (
), это обычная звезда, если отрицательная (
), это нейтронная звезда или
чёрная дыра. Значения — вещественные числа в условных единицах. Количество звёзд не превышает
1500.
В файле B хранятся данные о звёздах трёх кластеров, где ,
для каждого кластера. Количество
звёзд не превышает 5500. Структура данных аналогична файлу A.
Для каждого файла в каждом кластере найдите двойную систему из двух нейтронных звёзд () с
максимальной суммой масс по модулю. Затем вычислите два числа:
— среднее арифметическое абсцисс найденных
звёзд, и
— среднее арифметическое их ординат.
В ответе запишите четыре числа через пробел: сначала целую часть для файла A, затем
для
A, далее
для файла B и
для B.
Внимание! График приведён в иллюстративных целях для произвольных значений и не относится к заданию. Используйте данные из прилагаемого файла.
Оценим данные визуально, открыв файлы в и построив точечные диаграммы через раздел «Вставка
Диаграммы
Точечная».
Диаграмма для файла A:
Диаграмма для файла B:
Для кластеризации используем алгоритм DBSCAN с радиусом . Затем в каждом кластере применим DBSCAN с
радиусом
для поиска двойных систем. Оставим только пары из двух нейтронных звёзд (
) и
выберем ту, где сумма масс по модулю минимальна. Вычислим средние
и
для всех найденных
пар.
Код для файла A:
from math import * def dbscan(a, r): cl = [] # Инициализируем список для хранения кластеров while a: # Пока есть элементы в входном массиве ’a’ # Создаем новый кластер и добавляем в него первый элемент из ’a’ cl.append([a.pop(0)]) for i in cl[-1]: # Проходим по элементам последнего кластера # Проверяем каждый элемент ’j’ в оставшихся элементах ’a’ for j in a[:]: # Если расстояние между ’i’ и ’j’ меньше радиуса ’r’ x = [i[0], i[1]] y = [j[0], j[1]] if dist(x, y) < r: cl[-1].append(j) # Добавляем ’j’ в текущий кластер a.remove(j) # Удаляем ’j’ из списка ’a’, чтобы не проверять его снова return cl f = open("1_A.txt") a = [list(map(float, i.replace(",", ".").split())) for i in f] cl = dbscan(a, 0.5) cl_total = [] for i in cl: if len(i) > 10: cl_total.append(i) t = 0.15 ans = [] for i in cl_total: found_star = dbscan(i, t) duo_stars = [] mx_starsys = [] for j in found_star: if len(j) == 2: if -2.5 < j[0][2] < 0 and -2.5 < j[1][2] < 0: duo_stars.append(j) mx_mass = 0 for j in duo_stars: if abs(j[0][2] + j[1][2]) > mx_mass: mx_mass = abs(j[0][2] + j[1][2]) mx_starsys = j ans.append(mx_starsys) # Рассчитываем среднее значение res_X = 0 res_Y = 0 for i in ans: res_X += (i[0][0] + i[1][0]) res_Y += (i[0][1] + i[1][1]) print(int(abs(res_X / 4) * 200)) print(int(abs(res_Y / 4) * 200))
Код для файла B:
from math import * def dbscan(a, r): cl = [] # Инициализируем список для хранения кластеров while a: # Пока есть элементы в входном массиве ’a’ # Создаем новый кластер и добавляем в него первый элемент из ’a’ cl.append([a.pop(0)]) for i in cl[-1]: # Проходим по элементам последнего кластера # Проверяем каждый элемент ’j’ в оставшихся элементах ’a’ for j in a[:]: # Если расстояние между ’i’ и ’j’ меньше радиуса ’r’ x = [i[0], i[1]] y = [j[0], j[1]] if dist(x, y) < r: cl[-1].append(j) # Добавляем ’j’ в текущий кластер a.remove(j) # Удаляем ’j’ из списка ’a’, чтобы не проверять его снова return cl f = open("1_B.txt") s = f.readline() a = [list(map(float, i.replace(",", ".").split())) for i in f] cl = dbscan(a, 0.7) cl_total = [] for i in cl: if len(i) > 10: cl_total.append(i) t = 0.025 ans = [] for i in cl_total: found_star = dbscan(i, t) duo_stars = [] mx_starsys = [] for j in found_star: if len(j) == 2: if -2.5 < j[0][2] < 0 and -2.5 < j[1][2] < 0: duo_stars.append(j) mx_mass = 0 for j in duo_stars: if abs(j[0][2] + j[1][2]) > mx_mass: mx_mass = abs(j[0][2] + j[1][2]) mx_starsys = j ans.append(mx_starsys) # Рассчитываем среднее значение res_X = 0 res_Y = 0 for i in ans: res_X += (i[0][0] + i[1][0]) res_Y += (i[0][1] + i[1][1]) print(int(abs(res_X / 6) * 200)) print(int(abs(res_Y / 6) * 200))
Специальные программы

Программа
лояльности v2.0
Приглашай друзей в Школково и получай вознаграждение до 10%!

Крути рулетку
и выигрывай призы!
Крути рулетку и покупай курсы со скидкой, которая привязывается к вашему аккаунту.

Бесплатное онлайн-обучение
Для школьников из приграничных территорий России, проживающих в ДНР, ЛНР, Херсонской, Запорожской, Белгородской, Курской, Брянской областях и Крыму.

Налоговые вычеты
Узнай, как получить налоговый вычет при оплате обучения в «Школково».

Специальное предложение
для учителей
Бесплатный доступ к любому курсу подготовки к ЕГЭ, ОГЭ и олимпиадам от «Школково». Мы с вами делаем общее и важное дело, а потому для нас очень значимо быть чем-то полезными для учителей по всей России!

Вернём деньги за курс
за твою сотку на ЕГЭ
Сдать экзамен на сотку и получить обратно деньги за подготовку теперь вполне реально!