Heyo!
所以我得到了这个带有一堆顶点和边的有向和/或无向图。在该图中,有一个起始顶点和一个顶点。还有一个红色的顶点子集(该子集可以包括起始和结束顶点)。此外,没有一对顶点可以在它们之间具有多个边缘。
我要做的是找到:
A)没有通过红色顶点的最短路径
B)如果有一条通过至少一个红色顶点的路径
C)红顶点数量最多的路径
D)红顶点数量最少的路径
对于A,我使用广度优先搜索忽略红色分支。对于B我只是通过深度优先搜索图表来强制它。对于C和D,我使用动态编程,记忆我在所有路径中找到的红色顶点的数量,使用与B中相同的DFS。
我对所有解决方案都非常满意,我非常感谢任何建议!谢谢!
答案 0 :(得分:1)
对于A,我使用广度优先搜索忽略红色分支
A)是子图中发生的典型寻路问题,不包含红边。所以你的解决方案很好(如果你能拿出一个,那么可以通过启发式方法进行改进,然后使用A *)
对于B我只是通过深度优先搜索图表来强制它
这就是好事。每个最佳路径A->C
可以在任意中间点B
分割。最佳路径的一个不错的特性是每个子路径都是最佳的。因此A->B
和B->C
是最佳的。
这意味着,如果您知道,您必须从某些start
旅行到某些end
通过中间红色顶点,您可以执行以下操作:
交替扩展两个BFS,以便它们的“边缘”(或打开的列表,因为它们被称为)与它们各自的开始具有相同的距离。
停止时间:
C)红顶点数量最多的路径
这是一个组合问题。我要做的第一件事就是制作一个[start node + red nodes + end nodes]的可达性矩阵,其中:
reachability[i, j] = 1 iff there is a path from node i to node j
要计算此矩阵,只需从起始节点和每个红色节点开始执行一次BFS搜索。如果BFS到达红色节点,则在相应的行/列中放置1。
这将抽象出图的基本复杂性,并在组合搜索上加速一个数量级。
问题现在通过连接矩阵longest path problem。动态编程确实是可行的方法。
D)红顶点数量最少的路径
只需执行Dijkstra搜索,但在“打开”列表中对节点进行排序时使用以下指标:
dist(start, a) < dist(start, b) if:
numRedNodesInPath(start -> a) < numRedNodesInPath(start -> b)
OR (
numRedNodesInPath(start -> a) == numRedNodesInPath(start -> b)
AND
numNodesInPath(start -> a) < numNodesInPath(start -> a)
)
为此,在发现新顶点时,您必须在专用地图中存储通向它们的路径(好吧,只是路径中的nb节点,以及红色节点的nb)被拿走了。我提到这一点是因为通常,路径的长度隐含地存储为数组中verrtex的位置。在你的情况下,你必须明确地强制执行它。
关于长度最优性的注意事项:
即使您声明您不关心问题A)之外的长度最优性,我提供的算法将产生最短长度的解决方案。在很多情况下(比如D),我相信Dijkstra会更好地收敛。