创建一个N个随机(x,y,z)点的列表,这些点彼此之间的距离至少为r

时间:2019-07-10 19:45:38

标签: python

我正在尝试使用python创建N个随机(x,y,z)点的列表,以使每个点与其他任何点至少相距r。

我是编程的超级新手,到目前为止,我只能使用

分别生成x,y和z(然后放在一起)。
import random 
def RandX(start, end, num): 
    res = [] 

    for j in range(num): 
        res.append(random.randint(start, end)) 

    return res 
num = N
start = 0
end = 100
print(RandX(start, end, num)) 

但是我不知道如何控制或检查这些点(x,y,z)的位置,以使各点之间保持一定距离。

4 个答案:

答案 0 :(得分:1)

要检查两个点(x,y,z)和(a,b,c)(存储为元组)之间的距离,可以尝试:

def distance(p1,p2):
    d=0
    for i in range(3):
        d+=(p1[i]-p2[i])**2
    return d**(1/2)

一旦随机生成xyz,您可以设置以下内容:

p1=x,y,z
p2=a,b,c

如果您的数字不是太大,虽然效率很低,但是您可以生成随机数字,直到它们满足距离条件为止。

答案 1 :(得分:0)

类似这样的事情。 (它可以进行优化,但应该作为您的第一个版本)

from collections import namedtuple
import random
import math

Point = namedtuple('Point', ' x y z')

MIN = 0
MAX = 1000


def fill_points_list(points, number_of_required_points, min_distance):
    def _get_distance(p1, p2):
        return math.sqrt(sum([(a - b) ** 2 for a, b in zip(p1, p2)]))

    while len(points) < number_of_required_points:
        temp = Point(random.randint(MIN, MAX), random.randint(MIN, MAX), random.randint(MIN, MAX))
        count = 0
        for p in points:
            if _get_distance(temp, p) > min_distance:
                count += 1
            else:
                break
        if len(points) == count:
            points.append(temp)


number_of_required_points = 9
min_distance = 51
points = []

fill_points_list(points, number_of_required_points, min_distance)

print(points)

输出

[Point(x=771, y=590, z=226), Point(x=385, y=835, z=900), Point(x=551, y=294, z=800), Point(x=824, y=306, z=333), Point(x=892, y=548, z=879), Point(x=520, y=660, z=384), Point(x=409, y=193, z=331), Point(x=411, y=706, z=300), Point(x=272, y=116, z=719)]

答案 2 :(得分:0)

这是我的解决方案:我们所需要的只是一个距离函数和一个循环,用于生成随机点并检查已生成列表中的最小距离标准:

def dist(new_point, points, r_threshold):
    for point in points:
        dist = np.sqrt(np.sum(np.square(new_point-point)))
        if dist < r_threshold:
            return False
    return True


def RandX(N, r_threshold):
    points = []
    scope = np.arange(0,10,0.1)
    while len(points) < N:
        new_point = np.random.choice(scope, 3)
        if dist(new_point, points, r_threshold):
            points.append(new_point)
    return points

例如:

RandX(5, 4)
[array([3.5, 2.6, 7.6]),
 array([9.9, 0.1, 7.2]),
 array([4. , 2.8, 0.3]),
 array([0.2, 7.4, 5.1]),
 array([7.4, 6.3, 5.2])]

答案 3 :(得分:0)

您可以尝试随机生成多个点,然后根据距离标准对其进行过滤。 numpysklearn软件包可以帮助提高流程效率。您可以想象这样的事情:

import numpy as np
from sklearn.metrics.pairwise import euclidean_distances

r = 2

# Generate 100 points (3-tuples) between 0 and 10
points = np.random.randint(0,100,[1000,3])

# Pairwise distances between points
distances = euclidean_distances(points)

# "Remove" distance to itself by setting to a distance of r+1 (to discard it later)
distances += np.identity(len(distances)) * (r+1)

# Retrieve the distance to the closest point
min_dist = np.min(distances,axis=1)

# Filter your set of points
filtered_points = points[min_dist>r]

这应该运行得很快。