从3D空间中采样N个点的有效方法,并且在Python中两个点之间的最小距离受到限制

问题描述

我有200个数据点,每个点是代表位置的3个数字的列表。我想从此3D空间中采样N = 100个点,但是要限制在每两个点之间的最小距离必须大于0.15。下面的脚本是我对这些点进行采样的方式,但它始终保持运行并且永不停止。另外,如果我将N设置为大于某个值,则代码将找不到所有N个点,因为我随机采样了每个点,并且采样点到达了一个无法采样的点,该点与当前点不太接近,但是实际上,如果点分布非常“密集”(但仍满足大于0.15的最小距离),则N可能比该值大得多。有更有效的方法吗?

import numpy as np
import random
import time

def get_random_points_not_too_close(points,npoints,min_distance):
    random.shuffle(points)
    final_points = [points[0]]
    while len(final_points) < npoints:
        for point in points:
            if point in final_points:
                pass
            elif min([np.linalg.norm(np.array(p) - np.array(point)) for p in final_points]) > min_distance:
                final_points.append(point)

    return final_points


data = [[random.random() for i in range(3)] for j in range(200)]
t1 = time.time()
sample_points = get_random_points_not_too_close(points=data,npoints=100,min_distance=0.15)
t2 = time.time()
print(t2-t1)

解决方法

您的算法可能适用于一小组点,但它不会在确定的时间内运行。

我做了以下操作来创建一个随机森林(模拟树):首先生成一个方形点网格,其中网格点距离是最小距离的 3 倍。现在,您将规则网格中的每个点都沿随机方向平移,随机距离是最大距离。结果点永远不会比最大距离更近。

enter image description here