【问题标题】:Fastest way to find triangles from connected line points从连接线点找到三角形的最快方法
【发布时间】:2020-11-14 23:47:19
【问题描述】:

我想找到一种从连接线上检测所有三角形的方法。我有一个包含所有可用行的数组列表,称为 lines,当我添加另一行时,我想知道它是否会创建新的三角形。如下图所示,当我添加新行 f 时,它将点与索引 1,3 连接起来。我想要快速检测新三角形的创建并将索引 1,3,5 添加到另一个名为 triangles 的数组列表中。

// array with lines indices, each line contains two point indices
val lines: ArrayList<Int> = arrayListOf(
        0,1,  // a
        1,5,  // b
        5,4,  // c
        5,3,  // d
        5,2   // e
    )
val triangles: ArrayList<Int> = arrayListOf()

我想出的一种方法是创建一个数组列表,其中包含每个点的单独数组列表以及它所连接的所有索引。例如,索引为 5 的点与索引为 [1,2,3,4] 的点相连。因此,当添加连接索引 3,1 的新线时,我们可以检查是否 数组列表 circlesHash[3] 和 circlesHash[1] 包含相等的元素。在我们的例子中,两个数组都包含索引 5,这意味着创建了索引为 3,1,5 的三角形。如果数组列表是排序的,我可以使用 Arrays.binarySearch 方法。但是如果我有大量的点,例如 1000-2000 点,如果创建新三角形,最快的方法是什么?

val circlesHash: ArrayList<ArrayList<Int>> = arrayListOf(  
    arrayListOf(1),               // 0   
    arrayListOf(0,5),             // 1
    arrayListOf(5),               // 2
    arrayListOf(5),               // 3
    arrayListOf(5),               // 4
    arrayListOf(1,2,3,4)          // 5
)

另一个问题是是否有现有算法可以仅从现有线的索引中找到所有现有三角形。什么结构更可取 HashMaps、HashSet 或某种二叉树??

【问题讨论】:

    标签: algorithm line


    【解决方案1】:

    最简单的解决方案是通过共享点对边进行配对。因此,如果一个端点相同,则两条边是配对的。然后为每一对选择不被边共享的两个节点,在它们之间插入一条边,你就形成了一个三角形。假设您的图不是多重图,此算法不会产生任何重复并找到所有三角形。

    从那里我们可以创建一个不存在的边列表并将创建一个三角形。作为伪代码:

    triangle_candidates(g):
        triangle_edges = set()
    
        for e1 in g.edges:
            for e2 in g.edges:
                if e1 and e2 share a node:
                    a, b = nodes not shared by e1 and e2
                    if a and b are not neighbors:
                        triangle_edges.add(tuple(a, b))
    
        return triangle_edges
    
    creates_new_triangle(g, a, b):
        return tuple(a, b) in triangle_edges(g)
    

    请注意,元组被假定为无序的!上面的代码是基本原理的演示; triangle_candidates还有很大的优化空间。

    基本思想是创建一组所有节点对,这些节点对不是邻居,但如果连接则将完成一个长度为 3 的循环。检查一个新边是否会创建一个三角形是一个简单的集合查找,假设一个正确的实现应该相当快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-26
      • 2010-12-03
      • 2017-09-15
      • 2010-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-30
      相关资源
      最近更新 更多