c++ - 查找图中的最短路径,有附加限制

标签 c++ algorithm performance graph shortest-path

我有一个具有 2n 个顶点的图,其中每条边都有定义的长度。看起来像**

this

**。

我试图找到从uv的最短路径的长度(边长的最小总和),有两个额外的限制:

  • 路径包含的蓝色边的数量与红色边的数量相同。
  • 路径包含的黑边数量不大于p

我想出了一种我认为可行的指数时间算法。它按以下方式迭代表示从 u 开始的路径的长度 n - 1 的所有二进制组合:

  • 0 是蓝色边缘
  • 1 是红边
  • 每当出现黑边
    • 该组合以1开头。第一条边(来自 u)就是左侧的第一个黑色边。
    • 该组合以0结尾。那么最后一条边(到v)就是右边最后一个黑色的边。
    • 相邻数字不同。这意味着我们从蓝色边缘变为红色边缘(反之亦然),因此中间有一个黑色边缘。

该算法会忽略不满足前面提到的两个要求的路径,并计算满足的路径的长度,然后找到最短的路径。然而,这样做可能会非常慢,我正在寻找一些技巧来提出更快的算法。我怀疑可以通过动态编程来实现,但我真的不知道从哪里开始。任何帮助将不胜感激。谢谢。

最佳答案

看起来像Dynamic Programming对我来说是个问题。

In here, v,u are arbitrary nodes.
Source node: s
Target node: t

For a node v, such that its outgoing edges are (v,u1) [red/blue], (v,u2) [black].
D(v,i,k) = min { ((v,u1) is red ? D(u1,i+1,k) : D(u1,i-1,k)) + w(v,u1) ,
                  D(u2,i,k-1) + w(v,u2) }
D(t,0,k) = 0           k <= p
D(v,i,k) = infinity    k > p //note, for any v
D(t,i,k) = infinity    i != 0

说明:

  • v - 当前节点
  • 我 - #reds_traversed - #blues_traversed
  • k - #black_edges_left

停止子句位于目标节点,到达目标节点时结束,并且仅允许 i=0 且 k<=p

递归调用在每个点检查“哪个更好?穿过黑色还是穿过红色/蓝色”,并从两个选项中选择最佳解决方案。

这个想法是,D(v,i,k)是从v开始的最佳结果到目标(t),#reds-#blues使用的是 i ,您最多可以使用 k黑色边缘。
由此,我们可以得出D(s,0,p)是从源头到达目标的最优结果。

|i| <= n, k<=p<=n - 算法的总运行时间为 O(n^3) ,假设以动态规划实现。

关于c++ - 查找图中的最短路径,有附加限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33509276/

相关文章:

c++ - 如何创建自定义组件并将其添加到基于对话框的应用程序 (MFC)?

algorithm - 快速排序的基本困惑

java - 对 WeakReference.get() 对象的硬引用会导致内存泄漏吗?

C# 寻找一种线程安全且有效的方法来捕获跨多个命名空间的耗时

performance - Postgres Hstore 与 Redis - 性能方面

c++ - 单字分割算法

c++ - STL容器的 `less`参数如何工作?

c++ - ply文件格式的元素面是什么

c++ - 如何对此进行改进?

algorithm - WEKA J48和ID3算法输出的区别