【问题标题】:Connect nodes to neighbours via line of sight (straightline)通过视线(直线)将节点连接到邻居
【发布时间】:2022-01-25 04:19:54
【问题描述】:

所以我有一个类似于迷宫的结构,但空间更大。对于结构中的每个节点,我想找到它的所有“邻居”(如果节点在视线内,则节点是邻居,即没有墙挡住它们之间的直线)。

这里有一张小图可以帮助解释我的意思。

  • 黑线是墙。
  • 红点是节点。
  • 蓝线是连接邻居的线(注意没有蓝线与黑线交叉)。

我目前正在实施一种非常幼稚且极其昂贵的蛮力方法。在其中,我检查每个节点组合是否与任何迷宫墙(存储在“边缘”中的墙)相交。

for n1 in nodes:
    for n2 in nodes:
        if not intersect(n1, n2, edges):
            n1.neighbours.append(n2)
            n2.neighbours.append(n1)

这适用于像上面的 pexample 这样的小型结构。但我希望它能够扩展到更大的结构。

所以我的问题是,是否有任何方法可以更快/更有效地找到每个节点的所有邻居。

干杯:)

【问题讨论】:

    标签: python algorithm path-finding a-star maze


    【解决方案1】:

    您可能想阅读 Monge 关于射影几何的书 :)

    让我们在每个节点周围使用一个封闭式屏幕,正方形在计算上很容易,而圆形则需要更多的数学运算。屏幕是对节点隐藏空间的边的集合。 screen.occlude() 方法将您的一堵墙作为输入,计算屏幕上的投影,然后通过添加边缘或扩展边缘来扩展遮挡。

    结果是(很多?)遮挡边缘比墙壁少。 然后我们在遮挡边缘和节点上反转循环以获得时间。请注意,方法 .remove_occluded_by() 仅循环剩余的候选邻居,这是一个收缩集合。我猜增益是从 O(n^2) 到 O(n*log(n))

    您还可以在正方形的每一侧都有 2 个点,它们是该方向上遮挡的极端,可能是虚拟正方形的角。 4 个遮挡锥之外的每个节点都是可见的。不确定这是否会赢得时间。

    for n1 in nodes:
        n1.occlusion = a_1_by_1_square_occlusion( centre = n1 )
        for e in edges:
            n1.occlusion.occlude( e )
        n1.neighbours = nodes - n1                # your choice
        n1.neigbours.remove_connected_walls( n1 ) # your choice
        for o in n1.occlusion.edges:
            n1.neighbours.remove_occluded_by( o )
    

    【讨论】:

    • 谢谢,看来它可能会起作用。您能否提供更多有关屏幕遮挡以及具体工作原理的信息。干杯
    • @AstonKey 抱歉,我犯了一个错误,我的算法产生的光束穿过所有墙壁,它没有考虑候选节点和原始节点之间的距离。
    猜你喜欢
    • 2022-10-22
    • 2016-02-09
    • 2020-07-08
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    相关资源
    最近更新 更多