【问题标题】:Algorithm: Find repetitive groups in 2D-point distribution算法:在二维点分布中查找重复组
【发布时间】:2021-02-09 10:42:28
【问题描述】:

我目前正在从事一个有趣的项目,寻找二维点分布中的重复组。每组由四个点组成,其相对于彼此的位置受到一些边界条件的约束。我正在尝试找到一个自动组查找器和组匹配器。

点数据由二维数组组成。我们有 N 个点。

points = array[N,2]

每个组 ("tool") 由位于正方形 (length=L) 边缘的四个点 (a,b,c,d) 组成,但其位置可以是少量改变(位移=D)。这里的值是 L=1.000,D=0.150。

目前我目前的方法如下:

  1. 加载所有点数据(点)
  2. 迭代每个点p in points
  3. 搜索四个样方a、b、c、d内的所有点(相对于点p
  4. 对于所有找到的点 (a,b,c,d) 的每个组合 q
  5. 检查组合q是否可行(点间距离dist:L-Ddist
  6. 在工具列表TL中存储组合q

解析点数据后,我尝试找到最常用的工具。 toolList TL 是一个 8 维空间。但是因为每个步骤 4 都有很多组合,所以这个工具空间非常混乱。

您还有其他更好的方法吗?

附加您可以找到一些示例数据:


示例数据点(2 个组合,每个重复 10 次)

points =[[0.016,0.920],[0.995,1.080],[0.041,-0.069],[0.957,0.039],[1.496,1.081],[2.582,0.932],[1.536,0.015],[2.541,0.095],[0.516,1.420],[1.495,1.580],[0.541,0.431],[1.457,0.539],[1.996,1.581],[3.082,1.432],[2.036,0.515],[3.041,0.595],[1.016,1.920],[1.995,2.080],[1.041,0.931],[1.957,1.039],[2.496,2.081],[3.582,1.932],[2.536,1.015],[3.541,1.095],[1.516,2.420],[2.495,2.580],[1.541,1.431],[2.457,1.539],[2.996,2.581],[4.082,2.432],[3.036,1.515],[4.041,1.595],[2.016,2.920],[2.995,3.080],[2.041,1.931],[2.957,2.039],[3.496,3.081],[4.582,2.932],[3.536,2.015],[4.541,2.095],[2.516,3.420],[3.495,3.580],[2.541,2.431],[3.457,2.539],[3.996,3.581],[5.082,3.432],[4.036,2.515],[5.041,2.595],[3.016,3.920],[3.995,4.080],[3.041,2.931],[3.957,3.039],[4.496,4.081],[5.582,3.932],[4.536,3.015],[5.541,3.095],[3.516,4.420],[4.495,4.580],[3.541,3.431],[4.457,3.539],[4.996,4.581],[6.082,4.432],[5.036,3.515],[6.041,3.595],[4.016,4.920],[4.995,5.080],[4.041,3.931],[4.957,4.039],[5.496,5.081],[6.582,4.932],[5.536,4.015],[6.541,4.095],[4.516,5.420],[5.495,5.580],[4.541,4.431],[5.457,4.539],[5.996,5.581],[7.082,5.432],[6.036,4.515],[7.041,4.595]]

【问题讨论】:

  • x, y 坐标例如数据?
  • 还有例子 l, D.
  • 您需要反馈...

标签: python algorithm pattern-matching mathematical-optimization spatial


【解决方案1】:

假设l >> d 我将这些点放在一个 d 大小的网格上并寻找l // d 方格,然后转换回原始点。 请注意,不止一个点可以映射到同一个 d-grid 点,因此答案以表示正方形的列表形式给出。正方形是一个正方形的四个角点列表,其中任何角都可以由 d 邻域中的多个点表示。

import random
from collections import defaultdict


l = 205     # Square side
d = 25      # point +/- delta

# Up to max_points distinct integer points in range 0..r_max
r_max = 1_750
max_points = 1_000
points_x = random.sample(range(r_max), max_points)
points_y = random.sample(range(r_max), max_points)
points = list(set(zip(points_x, points_y)))


dgrid_2_points = defaultdict(list)  # Move points to d-sized grid
for x, y in points:
    dgrid_2_points[(x // d, y // d)].append((x, y))

d_l = l // d  # Square side in d-grids

d_points_set = set(dgrid_2_points)      # gridded points to check
d_points = sorted(d_points_set)         # order for checking

d_found = []            # Squares found on d-grid
for a in d_points:
    x, y = a
    b, c, d = (x, y+d_l), (x+d_l, y+d_l), (x+d_l, y)
    if all(p in d_points_set for p in (b, c, d)):
        d_found.append((a, b, c, d))
    d_points_set.remove(a)


found = [[dgrid_2_points[d_pt] for d_pt in d_square]
         for d_square in d_found]

"""
# EXAMPLE VALUE

found = \
[[[(236, 823), (240, 819)], [(239, 1018)], [(446, 1005)], [(425, 824)]],
 [[(540, 282)], [(534, 496)], [(726, 491)], [(733, 283)]],
 [[(586, 172)], [(585, 355)], [(794, 363)], [(797, 174)]],
 [[(755, 67)], [(763, 257)], [(972, 252)], [(958, 66)]],
 [[(924, 197)], [(912, 382)], [(1124, 393), (1104, 381)], [(1115, 181)]],
 [[(1375, 28)], [(1386, 245)], [(1581, 246)], [(1586, 43)]]]

"""

该示例显示它找到了六个正方形。找到的第一个正方形具有以下两个点中的任何一个作为一个角: [(236, 823), (240, 819)] 它的其他三个角是单个点。

注意:在我应该使用 d/2 网格而不是我使用的 d-grid 的地方可能会出现错误。你需要检查。在这种情况下,只需替换原始 d 值的一半并假设您正在报告 d。

您的示例要点

您现在已经给出了一组示例点。

  • 以您的分数运行,l 为 1,d 为 0.15 我发现 正方形。
  • d 乘以2,然后我找到六个正方形,其中一些角被多个点占据。
# YOUR EXAMPLE

l = 1.0
d = 0.15
points = ...

found = [] # Nothing

# Change d

d = 0.15 * 2

found = [
 [[(0.995, 1.08), (1.041, 0.931)], [(1.016, 1.92)], [(1.995, 2.08), (2.041, 1.931)], [(1.957, 1.039)]].
 [[(2.582, 0.932), (2.536, 1.015)], [(2.496, 2.081)], [(3.582, 1.932), (3.536, 2.015)], [(3.541, 1.095)]].
 [[(2.495, 2.58), (2.541, 2.431)], [(2.516, 3.42)], [(3.495, 3.58), (3.541, 3.431)], [(3.457, 2.539)]].
 [[(4.082, 2.432), (4.036, 2.515)], [(3.996, 3.581)], [(5.082, 3.432), (5.036, 3.515)], [(5.041, 2.595)]].
 [[(3.995, 4.08), (4.041, 3.931)], [(4.016, 4.92)], [(4.995, 5.08)], [(4.957, 4.039)]].
 [[(5.582, 3.932), (5.536, 4.015)], [(5.496, 5.081)], [(6.582, 4.932)], [(6.541, 4.095)]].]

这是你所期待的吗?

图表

红色是找到的正方形,蓝色延伸 +/- 半 d 以显示为拐角捕获的点。

【讨论】:

    猜你喜欢
    • 2015-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-02
    • 2017-07-22
    • 2021-06-09
    • 2013-10-17
    • 2020-07-16
    相关资源
    最近更新 更多