在无向和连通图中,每条边都有一种颜色(红色,绿色或蓝色) 有效路径是每种颜色至少有一条边的路径 问题是如何找到最短的有效路径或确定不存在。
我尝试使用BFS,但无法找出解决方案 关于如何开始的任何想法?
答案 0 :(得分:1)
我会使用BFS,并从每个节点开始,我将计算从该节点可发现的第一个有效路径,保存该值,然后继续下一个。
图形可以用矩阵表示,每条边的颜色(比如-1(无边),0,1,2)作为矩阵中边的值。
当您发现它们时,路径可以放入一对阵列中,一个用于保持路径中的步骤,另一个用于检查三种颜色。
答案 1 :(得分:1)
首先,我假设颜色的数量是固定的。 然后我会提出一个标签设置Dijkstra算法(与Pareto Dijkstra比较),导致运行时间为O(n log(n)+ m):
使用广义Dijkstra找到最短路径: 每个节点都有一个标签列表,一个标签由起始节点的长度和访问过的所有颜色组成。 如果(1)它具有较小的长度和(2)它包括另一个标签的所有颜色,则一个标签支配该节点中的另一个标签。直接删除主导标签。 与dijkstra类似,你保留了一个优先级队列,你可以从中放松长度较短的节点。将边缘移到节点v将使标签长度增加到边长,并将边缘的颜色添加到标签。标签将添加到节点v的标签列表中。 使用包含所有三种颜色的标签来确定目标节点时,您已找到最短路径。 请注意,如果要在最后重建最短路径,则必须为每个标签保存前导节点。
您从起始节点的初始标签开始,带有(0,{})(零长度,无颜色)。
每个颜色集组合最多可以安置一个节点,因为在这种情况下只存在8个(固定的)这样的组合,运行时间等于Dijkstra的算法 为最佳实现,这是O(n * log(n)+ m)。
答案 2 :(得分:0)
确实存在如下的微不足道的解决方案。
假设没有颜色,在图表上做正常的dijkstra。
猜测每种颜色的3条边。对于所有m ^ 3可能的猜测让边缘为r1 --- r2,b1 --- b2,g1 --- g2我们得到24种可能的方式它们可以进入路径(8种方式可以定位边缘,6为排列)。
由于你已经拥有了正常的dijkstra数据,所以一旦你完成了这个,你可以得到恒定的结果,最小化所有的猜测。
对所有n个顶点重复此操作。
我确实认为最终的复杂度O(nm ^ 3)通常太大,但有时候这个简单的算法是有效的。
答案 3 :(得分:0)
此问题可以通过产品构造来解决。创建一个新的 directed 图,其中每个顶点是原始图中一对顶点和颜色的子集。 (因此,对于3种颜色,新图形中每个图形在原始图形中的每个顶点将有8个顶点。)如果原始图形中的顶点与目标顶点的顶点之间存在一条边,则在新图形中的两个顶点之间添加一条边颜色集等于源顶点的颜色集加上原始图形中的边缘颜色(如果颜色已经在源顶点的颜色集中,则不变)。新的边缘应具有与原始边缘相同的权重。
然后新图中从( s ,∅)到( t ,{red,green,blue})的最短路径对应于<从使用所有3种颜色的原始图形中的em> s 到 t 。由于新图(假设有固定的颜色集)中仅线性地存在更多的顶点和边,因此该问题可以与渐近线的普通最短路径问题一样快地解决。
作为实现细节,请注意,实际上无需在内存中写下整个产品图。在运行最短路径算法时,可以动态生成顶点和边,从而可以完全跳过未使用的顶点。
此方法与eci's answer稍有不同,在于它扩展了顶点标签而不是路径权重。
我已经询问并回答了该问题here的更一般形式。
答案 4 :(得分:-1)
创建一个新图形(6次)由原始图形的三个副本组成,第一个仅包含其中一种颜色的边缘,第二种颜色包括另一种颜色的边缘,并将它们与来自边缘的边缘连接起来。第二种颜色,第三种副本将具有所有边缘,并连接到第二种图形,边缘来自第三种颜色。 然后运行dijkstra找到从s1到t3的最短路径。 因为我们不知道这个顺序是什么,我们将对整个6种可能的颜色顺序做同样的事情,然后选择我们得到的最短6条最短路径。