Эта проблема напоминает мне симуляцию частиц (в которой были подобные проблемы, как вы описали), которую я написал некоторое время go. Я нашел структуру данных, которая позволяет (с несколькими незначительными отклонениями на практике и при условии, что вы выбираете большое количество кусков) для сложности O (n).
Вы можете разделить имеющееся у вас двухмерное пространство на небольшой прямоугольник angular (я думаю, квадраты - лучшие в вашем случае) куски (с длиной стороны больше r
).
Тогда вам нужно O(n)
время, чтобы отсортировать точки по этим кускам.
Пусть k
будет общим количеством кусков, которое у вас есть.
Тогда для нахождения всех точек, находящихся в пределах радиуса r
для каждой точки, потребуется O(n*(n/k)) = O(n²/k)
, где n / k - приблизительное количество точек внутри каждого куска (при условии регулярного распределения, которое было верно для моделирования частиц, хотя не уверен в вашей проблеме). Имейте в виду, что для каждой точки вам также необходимо взглянуть на 8 соседних блоков!
Тогда у вас также есть дополнительный O(k)
, что объясняется тем фактом, что вам нужно перебирать фрагменты для доступа к элементам.
Таким образом, общая структура данных имеет сложность O(n²/k + n + k)
. Теперь, чтобы найти соотношение между n
и оптимальным k
, вы должны найти минимумы функции f(k) = a*n²/k + b*n + c*k
, что можно сделать, найдя производную и установив ее равной нулю:
f'(k) = -an²/k² + c = 0
→ n²/k² = c/a = constant
→ n пропорционально k, и поэтому, если k можно выбрать оптимальным:
O(n²/k + n + k) = O(n²/n + n+ n) = O(n)
Наихудший случай, конечно, все еще O(n²)
, когда k = 1