简体   繁体   English

过滤numpy随机选择的结果

[英]Filtering the result of numpy random choice

I want to filter the results generated by a numpy.random.choice . 我想过滤numpy.random.choice生成的结果。 The problem I want to solve cannot be solved using applying the condition first by using np.where and then making a random choice. 我要解决的问题无法通过首先使用np.where并随后进行随机选择来应用条件来解决。 In general, I want some property to hold among all the randomly chosen elements. 通常,我希望所有随机选择的元素中都包含一些属性。

The particular instance of this problem is that I want to pick n points in a plane at random such that any given pair of points is at least d distance apart. 这个问题的特殊情况是,我想随机选择一个平面中的n个点,以便任何给定的点对至少相距d距离。 I am not sure if this can be done in polynomial time since this problem looks like the NP-complete clique problem. 我不确定这是否可以在多项式时间内完成,因为这个问题看起来像是NP完全集团问题。

If it's not possible to obtain the required number of points, the algorithm is to be repeated using a lower value of d . 如果无法获得所需的点数,则应使用较低的d重复该算法。

A direct approach would be to generate your array point by point and checking that each new point respects your condition. 一种直接的方法是逐点生成数组,并检查每个新点是否符合您的条件。 Here is how you could do it : 这是您可以执行的操作:

import math
import random

# We define a distance function
def distance(x1, y1, x2, y2):
    return math.sqrt((x2-x1)**2+(y2-1)**2)

# We define a function that checks if a new point respects the distance condition
def distance_respected(points, dist_max, new_x, new_y):
    distance_respected = True
    for point in points:
        if distance(point[0], point[1], new_x, new_y)>dist_max:
            distance_respected = False
    return distance_respected

# In the following example I decided to just consider part of a plane. More precisely
# [-10,10]*[-10,10]

number_of_points = 5
max_distance = 2
points = []
for point in range(number_of_points):
    # random.uniform() generates a random float between our two numbers
    new_x = random.uniform(-10,10)
    new_y = random.uniform(-10,10)
    while not distance_respected(points, max_distance, new_x, new_y):
        new_x = random.uniform(-10,10)
        new_y = random.uniform(-10,10)
    points.append((new_x, new_y))

Output : 输出:

[(-3.425486982794177, -5.415726177177236),
 (-4.109629395121301, -0.8693732638893792),
 (-2.2778596980094257, 1.1101779439932162),
 (-3.0579069964130916, 1.2909258679375473),
 (-3.067639560760325, 1.1507562378468599)]

Poisson disc sampling is good for this. 泊松圆盘采样对此非常有用 The runtime is nothing like NP-complete. 运行时不像NP-complete。

The algorithm is basically "keep a list of hot points and choose other hot points near them. If you can't find one nearby in a few tries, make the point cold forever." 该算法基本上是“保留热点列表并选择附近的其他热点。如果几次尝试都找不到附近的热点,则将其永久冷却。”

You'll need a quadtree (or similar) to make finding nearby points efficient. 您将需要一个四叉树(或类似的树)来提高附近点的查找效率。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM