Эффективно найдите приблизительное минимальное остовное дерево большого графа

У меня большое количество узлов, ~25000, каждый из которых имеет трехмерную позицию.

Я хочу создать разреженный граф с ребрами, определяемыми расстоянием между узлами, для использования в GNN.

Алгоритмы поиска минимального связующего дерева (MST) обычно основаны на том, что сначала начинается с полностью связного графа, а затем удаляются узлы для поиска MST. Это очень медленно для больших графиков.

Чтобы ускорить этот процесс, я попытался использовать sparse_distance_matrix scipy, чтобы ограничить радиус начальных соединений максимальным расстоянием до ближайшего соседа, но это приводит к появлению нескольких связных компонентов для некоторых графов.

(Пример меньшего графика этого метода не работает:)

Вот что я пробовал:

import numpy as np
from scipy.sparse.csgraph import minimum_spanning_tree
from scipy.spatial import KDTree
from scipy.spatial import distance_matrix

# Create a random set of 25000 node positions
positions = np.random.normal(loc=500000, scale=10000, size=(25000, 3))

# Method 1: Full MST Search (Too Slow)
dist_matrix = distance_matrix(positions, positions)
mst = minimum_spanning_tree(dist_matrix)


# Method 2: Start from sparse matrix (Results in multiple connected components)
kdtree = KDTree(positions)

# Find the maximum nearest neighbour distance for the graph
distances, _ = kdtree.query(positions, k=2)
max_neighbour_distance = np.max(distances[:, 1])
max_neighbour_distance = np.ceil(max_neighbour_distance) # Round up to avoid floating point errors in MST search


# Threshold the distance matrix by this distance
sparse_dist_matrix = kdtree.sparse_distance_matrix(kdtree, max_neighbour_distance, output_type = "coo_matrix")

mst = minimum_spanning_tree(sparse_dist_matrix)

G = nx.from_scipy_sparse_array(mst)

Мне не нужно истинное минимальное остовное дерево, просто чтобы граф был связан с как можно меньшим количеством ребер, чтобы ускорить производительность GNN. Даже разреженный метод слишком медленный для некоторых графов.

Я рассматривал метод, основанный на https://www.cs.umd.edu/~mount/Papers/soda16-emst.pdf, но его сложно реализовать, т. е. в scipy нет квадродеревьев.

Преобразование полной матрицы расстояний в граф networkx с последующим использованием реализации алгоритма Борувки происходит еще медленнее, оно не предназначено для больших графов. Добавление множителя к max_neighbor_distance поможет гарантировать наличие только одного подключенного компонента, но также увеличит время обработки, которого не всегда будет достаточно.

Одним из способов гипотетически сделать это является многопоточный подход с несколькими входами и синхронизатором для мониторинга всех потоков, избегая при этом повторного посещения вершин и, в конечном итоге, сообщая о MST. Короче говоря, это просто поиск MST одновременно с использованием нескольких начальных вершин.

M.A. 29.07.2024 10:07

Алгоритм Краскала добавляет ребра для построения MST.

David Conrad 29.07.2024 19:11
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

остовное дерево минимума евклидова расстояния для набора точек является подграфом триангуляции Делоне, который имеет линейное число ребер.

В Scipy есть метод для эффективного расчета триангуляции Делоне.

Большое спасибо. Вот новая реализация, которую может использовать каждый в будущем: gist.github.com/DoctorDinosaur/f00e131b2ce8a6bac18445322d794‌​ec5

DrDino 29.07.2024 14:06

Другие вопросы по теме