图中的约束最短路径

时间:2013-02-27 06:45:59

标签: algorithm

这是我在网上法官网站上发现的问题:

我有一个无向图(带有循环)。我们在图中有不同类别的顶点。您可以将第1类顶点视为绿色,将第2类顶点视为红色,依此类推。还有一类特殊的顶点颜色(稍后)。

现在,用户将指定源顶点,目标顶点和一系列不同顶点类(非白色),例如。

我们获得了源顶点10,目标顶点40和序列:红色 - >蓝色 - >黑色。

我们必须找到最短路径,使得路径从顶点10开始,接触1个红色顶点,然后是1个蓝色和1个黑色顶点,然后到达顶点40。然而,路径可以根据需要拥有尽可能多的白色顶点。它还可以遍历白色顶点两次。

因此解决方案可以是:10-> 20(白色) - > 35(红色) - > 21(白色) - > 22(白色) - > 30(蓝色) - > 34(黑) - →40

不正确:

10→20(白色) - →30(蓝色) - > 21(白色) - > 22(白色) - →35(红色) - > 34(黑色) - →40 (在红色之前变为蓝色)

10→20(白色) - →35(红色) - > 56(红色) - > 21(白色) - > 22(白色) - →30(蓝色) - > 34 (黑色) - > 40(穿过红色两次)

3 个答案:

答案 0 :(得分:1)

你可以使用dijkstra算法和附加标志来显示顶点的路径是否满足条件。

答案 1 :(得分:1)

假设A1 (稍后解除):序列S中没有颜色存在两次。

然后我们可以使用以下算法B1

  1. 在有向图G'中以下列方式变换图G:
    • G'与G
    • 具有相同的节点
    • 如果v是白色节点且G中存在(v,u),则将(v,u)和(u,v)插入G'
    • 如果(v,u)存在于G中,(color(v),color(u))存在于S中,则插入(v,u)in G'
    • 忽略G的所有其他边(包括循环)。
  2. 为所有边缘指定相同的权重
  3. 在G'上执行最短路径算法,例如,Bellman-Ford
  4. 现在我们放松A1:假设A2:在S中只有一种颜色存在多次

    算法B2

    1. wl.o.g.,c0是在S中存在多次的颜色,更确切地说是n次。
    2. 将S分为子序列S1,S2,...,其中S1 =(c1,c2,...,c0),S2 =(c3,...,c0)......
    3. 通过关于每个S_i
    4. 的B1的步骤1的变换G生成图G1,G2 ......
    5. 通过连接G1,G2,...... Gn形成图G'
      • 将每个节点与G1中的颜色c0连接,颜色为c3的每个节点和G2
      • 中的任何白色节点
      • 对G2和G3等做同样的事。
    6. 在G1中使用源最短路径algortihm,在Gn
    7. 中应用目标

      延伸到序列中的几种重复颜色:

      将序列拆分为没有重复颜色的序列,并类似地应用B2。

答案 2 :(得分:1)

我可以根据使用bfs修改完成的简单图形修改建议 O(n *(n + m))解决方案。让我一步一步地描述它。

图表修改。

  1. 为了避免任何麻烦,颜色来源和白色顶点呈现出某种独特的颜色。
  2. 制作图表加权。原始边缘的重量 1
  3. 对于每对彩色顶点 u,v 添加边(u,v),其权重等于从u到v的最短白色路径。 白色路径是仅通过白色顶点的路径。如果没有这样的白色路径,请不要添加边缘。
  4. 删除所有白色顶点及其相邻边。
  5. 第二点可以通过从仅通过白色顶点的每个顶点运行 bfs 来完成。这将在O(n *(n + m))中运行。

    <强>等价性。

    现在我们有一个没有白色顶点的加权彩色图形,并且很容易看到修改后问题保持不变 - 我们仍然需要找到从源顶点到目标顶点的最短路径(现在就边缘权重和而言)。

    搜索算法。

    要解决此图表上的问题,请运行bfs的变体,其中的图层对应于提供的路径的颜色。这意味着,如果给出路径为红色 - >蓝色 - >黑色,则第一个移动bfs将进入与源相邻的所有红色顶点,然后移动到与那些红色标记相邻的所有蓝色,然后到达与那些相邻的所有黑色蓝色标记,最后到目标。当某个顶点被推入bfs队列时,请记住它的路径长度以备将来使用。

    <强>伪代码。

    1. currentVertexes = {(source,0)} //顶点和路径长度
    2. i 0 到sizeof givenPath 执行
      1. nextColor = givenPath [i]
      2. nextVertexes = {}
      3. for (v,len) in currentVertexes
        for all u s.t.存在边 e:=(v,u) u.color = nextColor
        nextVertexes .insert((u,len + e.length))
      4. currentVertexes = nextVertexes
    3. 选择存储在 currentVertexes 中的最小长度,因为只有(目标,长度)对。
    4. <强>复杂度:

      图形修改需要 O(n *(n + m))运行时间,第二部分将运行 O(n * n),因为给定的长度path不能超过n(语句中没有颜色重复),并且在每一步中 currentVertexes 中最多只能有n个顶点。总复杂度为 O(n *(n + m))+ O(n * n)= O(n *(n + m))