Существует несколько структур данных для эффективных запросов ближайших соседей. Для 3d kdtree работает очень хорошо и имеет сложность O (log n) для каждого запроса в среднем, что улучшило бы ваше текущее O (n).
Таким образом, с помощью этой структуры вы можете добавить к ней все свои точки из кластеров, а затем для каждой точки в точках вы можете использовать структуру для запроса ближайшей точки. Для вашего конкретного случая достаточно статического kdtree, так как вам не нужно обновлять точки.
Другой подход :
Мы можем попытаться рискнуть сделать дополнительные вычисления для некоторых пунктов в обмен на меньшее на другие. Этот метод должен хорошо работать со следующими допущениями:
- Расстояние между кластером и другим далеко
- Расстояние между точкой и соседней точкой невелико
Я думаю, что это применимо к вашему случаю, потому что у ваших кластеров мало цветов, а ваши точки получены из реального изображения, которое имеет тенденцию иметь похожие цвета между соседними пикселями.
Для каждой точки создайте кучу. Вместо того, чтобы хранить ближайший кластер, сохраните в max heap ближайший k кластеров. Когда вы переходите к следующему пункту, мы можем использовать эту информацию. Назовем эту точку P и ее k-й ближайший кластер C.
Теперь для новой точки P2, перед сравнением со всеми кластерами мы проверим, находится ли ближайший кластер к P2 в нашей куче. Это может быть верно только в том случае, если расстояние между любым кластером от кучи и P2 равно <= distance (P, C) - distance (P, P2). Когда это верно, мы можем проверять только в нашей куче, а не во всех кластерах. Когда это не так, мы сравниваем все и перестраиваем нашу кучу, а P будет P2. </p>
Вам нужно будет попробовать разные значения k, чтобы посмотреть, улучшится ли он. В случае K = 2, возможно, стоит избегать дополнительной сложности кучи и просто использовать переменные.