В лаборатории проводится эксперимент, состоящий из множества испытаний. Результат каждого испытания представляется в виде пары чисел.
Для визуализации результатов эта пара рассматривается как координаты точки на плоскости, и на чертеже отмечаются точки, соответствующие всем испытаниям.
По результатам эксперимента проводится кластеризация полученных результатов: на плоскости выделяется несколько кластеров — кругов радиуса не более 3 единиц так, что каждая точка попадает ровно в один кластер.
Центром кластера считается та из входящих в него точек, для которой минимально среднее из расстояний до всех остальных точек кластера.
При этом расстояние вычисляется по стандартной формуле расстояния между точками на евклидовой плоскости.
Радиусом кластера считается максимальное из расстояний от центра до остальных точек кластера.
Обработка результатов эксперимента включает следующие шаги:
1) кластер, содержащий наибольшее число точек, исключается;
2) определяются центры и радиусы всех оставшихся кластеров;
3) вычисляется средний радиус оставшихся кластеров.
В файле записан протокол проведения эксперимента. Каждая строка файла содержит два числа: координаты X и Y точки, соответствующей одному испытанию. По данному протоколу надо определить средний радиус всех кластеров за исключением содержащего наибольшее число точек.
Вам даны два входных файла (A и B), каждый из которых имеет описанную выше структуру. По данным каждого из представленных файлов определите средний радиус по описанным выше правилам.
В ответе запишите два числа: сначала средний радиус для файла A, затем для файла B.
В качестве значения указывайте целую часть от умножения найденного числового значения на 10 000.
Ответ:
Построим диаграммы для файла А и Б. Для этого воспользуемся табличным редактором.
Диаграмма для файла А:
Диаграмма для файла Б:
Приведём решение на языке Python для файла А.
import math
def dist(p1, p2):
x1, y1 = p1
x2, y2 = p2
return ((x1 - x2)**2 + (y1 - y2)**2) ** 0.5
def center_of_cluster(kl):
# Возвращает центр кластера: точку с минимальной суммой расстояний до остальных
if not kl:
return None
if len(kl) == 1:
return kl[0]
best_center = None
best_sum_dist = float('inf')
for p in kl:
s = sum(dist(p, q) for q in kl)
if s < best_sum_dist:
best_sum_dist = s
best_center = p
return best_center
def radius_of_cluster(center, kl):
if center is None or not kl:
return 0.0
return max(dist(center, q) for q in kl)
def mean_radius_after_exclusion(points):
# 1) кластеризация по эвристике
clusters = [[] for _ in range(3)]
for x, y in points:
if y < 2:
clusters[0].append((x, y))
elif x < 3:
clusters[1].append((x, y))
else:
clusters[2].append((x, y))
# 2) исключаем кластер с наибольшим количеством точек
if clusters:
largest = max(clusters, key=len)
clusters.remove(largest)
# Если после исключения кластеров не осталось
remaining_clusters = [kl for kl in clusters if kl]
if not remaining_clusters:
return 0.0
centers = [center_of_cluster(kl) for kl in remaining_clusters]
radii = [radius_of_cluster(c, kl) for c, kl in zip(centers, remaining_clusters)]
avg_radius = sum(radii) / len(radii) if radii else 0.0
return avg_radius
def load_points_from_file(filename):
pts = []
try:
with open(filename, 'r') as f:
for line in f:
line = line.strip()
if not line:
continue
# Разделяем по пробелам и берём первые две чисел
parts = line.split()
if len(parts) >= 2:
x = float(parts[0])
y = float(parts[1])
pts.append((x, y))
except FileNotFoundError:
pass
return pts
def compute_mean_radius_for_file(filename):
pts = load_points_from_file(filename)
return mean_radius_after_exclusion(pts)
file_A = "27A.txt"
mean_A = compute_mean_radius_for_file(file_A)
out_A = int(math.floor(mean_A * 10000.0 + 1e-12))
print(out_A)
Приведём решение на языке Python для файла B.
import math
def dist(p1, p2):
x1, y1 = p1
x2, y2 = p2
return ((x1 - x2)**2 + (y1 - y2)**2) ** 0.5
def center_of_cluster(kl):
# Возвращает центр кластера: точку с минимальной суммой расстояний до остальных
if not kl:
return None
if len(kl) == 1:
return kl[0]
best_center = None
best_sum_dist = float('inf')
for p in kl:
s = sum(dist(p, q) for q in kl)
if s < best_sum_dist:
best_sum_dist = s
best_center = p
return best_center
def radius_of_cluster(center, kl):
if center is None or not kl:
return 0.0
return max(dist(center, q) for q in kl)
def mean_radius_after_exclusion(points):
# 1) кластеризация по эвристике
clusters = [[] for i in range(5)]
for x, y in points:
if x < -1.5:
clusters[0].append((x,y))
elif x > 4 and y >6:
clusters[1].append((x,y))
elif y > 5:
clusters[2].append((x,y))
elif x > 2:
clusters[3].append((x,y))
else:
clusters[4].append((x,y))
# 2) исключаем кластер с наибольшим количеством точек
if clusters:
largest = max(clusters, key=len)
clusters.remove(largest)
# Если после исключения кластеров не осталось
remaining_clusters = [kl for kl in clusters if kl]
if not remaining_clusters:
return 0.0
centers = [center_of_cluster(kl) for kl in remaining_clusters]
radii = [radius_of_cluster(c, kl) for c, kl in zip(centers, remaining_clusters)]
avg_radius = sum(radii) / len(radii) if radii else 0.0
return avg_radius
def load_points_from_file(filename):
pts = []
try:
with open(filename, 'r') as f:
for line in f:
line = line.strip()
if not line:
continue
# Разделяем по пробелам и берём первые две чисел
parts = line.split()
if len(parts) >= 2:
x = float(parts[0])
y = float(parts[1])
pts.append((x, y))
except FileNotFoundError:
pass
return pts
def compute_mean_radius_for_file(filename):
pts = load_points_from_file(filename)
return mean_radius_after_exclusion(pts)
file_B = "27B.txt"
mean_B = compute_mean_radius_for_file(file_B)
out_B = int(math.floor(mean_B * 10000.0 + 1e-12))
print(out_B)
Ответ: 9142; 11309.

