Тема 27. Анализ данных

27.06 Поиск двойных/тройных звездных систем

Вспоминай формулы по каждой теме
Решай новые задачи каждый день
Вдумчиво разбирай решения
ШКОЛКОВО.
Готовиться с нами - ЛЕГКО!
Подтемы раздела анализ данных
Решаем задачу:

Ошибка.
Попробуйте повторить позже

Задача 1#105882

Учёный решил провести кластеризацию некоторого множества звёзд по их расположению на карте звёздного неба. Кластер звёзд – это набор звёзд (точек) на графике, каждая из которых находится от хотя бы одной другой звезды на расстоянии не более R  условных единиц. Каждая звезда обязательно принадлежит только одному из кластеров.

Тройная звездная система – это система, в которой три звезды попарно находятся на расстоянии не более t  . При этом других звезд на расстоянии менее t  у этих трех звезд быть не должно.

Под расстоянием понимается расстояние Евклида между двумя точками A(x1,y1)  и B(x2,y2)  на плоскости, которое вычисляется по формуле:

        ∘ --------------------
d(A, B) =  (x2 − x1)2 + (y2 − y1)2

Аномалиями назовём точки, находящиеся на расстоянии более одной условной единицы от точек кластеров. При расчётах аномалии учитывать не нужно.

В файле A хранятся данные о звёздах трех кластеров, где R = 0.45  , t = 0.02  для каждого кластера. В каждой строке записана информация о расположении на карте одной звезды: сначала координата x  , затем координата y  . Значения даны в условных единицах, которые представлены вещественными числами. Известно, что количество звёзд не превышает 3000.

В файле Б хранятся данные о звёздах четырех кластеров, где R = 0.45  , t = 0.01  для каждого кластера. Известно, что количество звёзд не превышает 10 000. Структура хранения информации о звездах в файле Б аналогична файлу А.

Для каждого в каждом кластере файла найдите тройную звезду, которая образует треугольник с наименьшим периметром. Затем вычислите два числа: Px  — среднее арифметическое абсцисс найденных звезд, и Py  – среднее арифметическое ординат найденных звезд.

В ответе запишите четыре числа через пробел: сначала целую часть произведения |P |⋅10000
  x  для файла А, затем |Py|⋅10000  для файла А, далее целую часть произведения |Px|⋅10000  для файла Б и |Py|⋅10000  для файла Б.

Возможные данные одного из файлов иллюстрированы графиком.

Внимание! График приведён в иллюстративных целях для произвольных значений, не имеющих отношения к заданию. Для выполнения задания используйте данные из прилагаемого файла.

PIC

Вложения к задаче
Показать ответ и решение

Для начала визуально оценим данные в условии кластеры. Для этого откроем предложенные файлы в Excel  , перейдем в раздел «Вставка → Диаграммы → Точечная».

Диаграмма для файла А имеет вид:

PIC

Диаграмма для файла Б имеет вид:

PIC

Для разделения звезд на кластеры будем использоваться функцию dbscan. Дальше основная идея решения будет заключаться в том, что мы будем проходить по каждой точке в найденных кластерах и с помощью того же метода dbscan для каждого кластера найти списки звезд, расстояние между которыми менее 0.01. Далее в каждом кластере нужно оставить только те списки, в которых количество звезд равно трем – то есть только тройные звездные системы. В конце остается дело за малым: для каждой звездной системы в каждом кластере найти максимальное расстояние между звездами а затем расчитать среднее расстояние между всеми найденными парами.

Код программы

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’
                if dist(i, j) <= r:
                    cl[-1].append(j) # Добавляем ’j’ в текущий кластер
                    a.remove(j) # Удаляем ’j’ из списка ’a’, чтобы не проверять его снова
    return cl

f = open("2.txt")
s = f.readline()
a = [list(map(float, i.replace(",", ".").split())) for i in f]
cl = dbscan(a, 0.45)
cl_total = []
for i in cl:
    if len(i) > 10: cl_total.append(i)

t = 0.02 # Для файла А
t = 0.01 # Для файла Б
ans = []
for i in cl_total: # Проходим по каждому элементу в списке cl_total
    found_star = dbscan(i, t) # Применяем алгоритм DBSCAN
    tr_stars = [] # Список для тройных звездных систем
    mn_starsys = [] # Список для хранения звездной системы с максимальным расстоянием
    # Проходим по каждому кластеру, найденному алгоритмом DBSCAN
    for j in found_star:
        if len(j) == 3: # Проверяем, состоит ли кластер из трех звезд
            # Проверяем является ли остроугольным треугольником
            d1 = dist(j[0], j[1])
            d2 = dist(j[0], j[2])
            d3 = dist(j[1], j[2])
            if (d1 <= t) and (d2 <= t) and (d3 <= t):
                tr_stars.append(j)
    mn_per = 100000000000 # Переменная для хранения максимального длины стороны
    for j in tr_stars: # Проходим по всем найденным тройным системам
                                                                                                  
                                                                                                  
        # Вычисляем периметр
        d1 = dist(j[0], j[1])
        d2 = dist(j[0], j[2])
        d3 = dist(j[1], j[2])
        if d1 + d2 + d3 < mn_per:
            mn_per = d1 + d2 + d3 # Обновляем максимальное расстояние
            mn_starsys = j # Сохраняем текущую звездную систему как систему с максимальным расстоянием
    ans.append(mn_starsys)

# Рассчитываем среднее значение
res_X = 0
res_Y = 0
for i in ans:
    res_X += (i[0][0] + i[1][0] + i[2][0])
    res_Y += (i[0][1] + i[1][1] + i[2][1])

print(int(abs(res_X / 9) * 10000))  # Для файла А
print(int(abs(res_Y / 9) * 10000))  # Для файла А

print(int(abs(res_X / 12) * 10000))  # Для файла Б
print(int(abs(res_Y / 12) * 10000))  # Для файла Б

Ответ: 3746 15629 58241 3102

Специальные программы

Все специальные программы

Программа
лояльности v2.0

Приглашай друзей в Школково и получай вознаграждение до 10%!

Крути рулетку
и выигрывай призы!

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

Бесплатное онлайн-обучение

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

Налоговые вычеты

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

Специальное предложение
для учителей

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

Вернём деньги за курс
за твою сотку на ЕГЭ

Сдать экзамен на сотку и получить обратно деньги за подготовку теперь вполне реально!

cyberpunkMouse
cyberpunkMouse
Рулетка
Вы можете получить скидку в рулетке!