在Python中按位置对坐标点列表进行有效分组

在Python中按位置对坐标点列表进行有效分组,python,algorithm,grid,Python,Algorithm,Grid,给定二维网格上的X、Y坐标点列表,创建相邻坐标点组列表的最有效算法是什么 例如,给定由网格(15x15)上两个非相邻正方形(3x3)组成的点列表,该算法的结果将是两组点对应于两个正方形 我想您可以使用泛洪填充算法,但对于1024大小的大型2D阵列来说,这似乎有些过分,效率也不是很高。不清楚您所说的“相邻坐标点组”是什么意思。您的两个不相邻的3x3正方形示例表明您正在寻找所谓的 有许多实现可以提取连接的组件。以下是一些指南 然而,我已经实现了这种blob检测器,如果你想获得学习经验的话,写它

给定二维网格上的X、Y坐标点列表,创建相邻坐标点组列表的最有效算法是什么

例如,给定由网格(15x15)上两个非相邻正方形(3x3)组成的点列表,该算法的结果将是两组点对应于两个正方形


我想您可以使用泛洪填充算法,但对于1024大小的大型2D阵列来说,这似乎有些过分,效率也不是很高。

不清楚您所说的“相邻坐标点组”是什么意思。您的两个不相邻的3x3正方形示例表明您正在寻找所谓的

有许多实现可以提取连接的组件。以下是一些指南

  • 然而,我已经实现了这种blob检测器,如果你想获得学习经验的话,写它们并不难。如果没有,那么我将使用最成熟的库,如OpenCV,如果您需要的话,使用他们的Python API


    另外,你提到了“效率”。请注意,这些算法有单通和双通版本。顾名思义,单次传递通常更有效,因为它只需要单次传递数据。如果网格非常大,可能需要这样做。

    可以对所有坐标点进行散列(例如,使用python中的字典结构),然后对每个坐标点的相邻点进行散列,以找到相邻点对并“合并”它们。此外,对于每个点,可以维护指向该点所属连接组件的指针(使用字典结构),对于每个连接组件,可以维护属于该组件的点列表


    然后,当散列点的邻居并找到匹配项时,合并点所属的两个连接组件集,并更新联合集中所有新点的组指针。您可以显示只需对所有点的所有邻居进行一次散列,这将找到所有连接的组件,而且,如果在合并两个连接的组件集时更新两个连接的组件集中较小的组件集的指针,则运行时的点数将是线性的。

    ,这是一个图像处理操作。如果您使用图像处理库(又称“skimage”),这将很容易。处理海量数据的速度最终会变慢,但1024x1024算不了什么

    [1]中的
    :将numpy作为np导入
    在[2]中:导入撇渣
    在[3]中:x=[0,1,2,0,1,2,0,1,2,-3,-2,-1,-3,-2,-1,-3,-2,-1]
    在[4]中:y=[0,0,0,1,1,2,2,2,-3,-3,-2,-2,-1,-1]
    在[5]中:稠密=np.零((9,9),dtype=布尔)
    [6]中:稠密[y,x]=真
    In[7]:打印(密集)
    [[True-True-False-False-False]
    [真假假假假]
    [真假假假假]
    [假假假假假假假]
    [假假假假假假假]
    [假假假假假假假]
    [假假假假真真]
    [假假假假真真]
    [假假假假真真]]
    [8]中:标记=撇渣.形态学.标记(稠密)
    在[9]中:打印(带标签)
    [[1 1 1 0 0 0 0 0 0]
    [1 1 1 0 0 0 0 0 0]
    [1 1 1 0 0 0 0 0 0]
    [0 0 0 0 0 0 0 0 0]
    [0 0 0 0 0 0 0 0 0]
    [0 0 0 0 0 0 0 0 0]
    [0 0 0 0 0 0 2 2 2]
    [0 0 0 0 0 0 2 2 2]
    [0 0 0 0 0 0 2 2 2]]
    在[10]中:coords_yx={i:(labeled==i).nonzero()表示范围(1,labeled.max()+1)}
    在[11]中:coords_yx
    出[11]:
    {1:(数组([0,0,0,1,1,1,2,2]),数组([0,1,2,0,1,2,0]),
    2:(数组([6,6,6,7,7,7,8,8]),数组([6,7,8,6,7,8]))
    
    两点何时相邻?根据您的要求,使用欧几里德距离的最短路径算法可能会很好。当两个点彼此在1个单位内时,它们是相邻的。所以(2,2)与(2+/-1,2+/-1)相邻。如何使用最短路径算法?嗯,我还没有想清楚;创建图形需要n^2个时间,但也可以在这段时间内进行简单的成对检查。我真的不明白你怎么能按照这个概念来分组;你可以得到属于多个簇的点,但这可能是故意的。你不能有一个点与两个簇相邻,因为那将是一个簇,除非我不正确。哦,你是说它会传播?如中所示,如果有(0,0)、(1,0)和(2,0),则它们都属于同一组,即使(0,0)和(2,0)之间的距离是2?那么我肯定误解了这个问题。你知道实现的算法的时间复杂度是多少吗?我还没有分析这些算法的实现。我使用了MATLAB函数,但它是用于一个小问题,吞吐量不是问题。但是,单遍实现不应要求超过O(V+E),其中V=顶点,E=边。对于网格实现,当您通过坐标时,您所要做的就是检查它与您后面的坐标的邻接关系。这应该是线性的,而且相当有效。OP说他在网格上有坐标。网格是一个图形。尽管这是一个非常专业的图表。坐标定义顶点,其邻接定义边。如果它在网格中(如果我正确理解OP问题),你不必对坐标进行排序……我完全忽略了这一点。我将很快删除这一条和最后一条评论。尽管如此,他只是说它们在一个网格上,并不是说他把它们作为一个网格图。我尝试了你的建议,它对块状形状很有效,但蛇形形状往往会被错误地分成两组。这是我的密码: