考虑一个有n
节点和m
边的有向图。每条边都被加权。有一个开始节点s
和一个结束节点e
。我们希望找到从s
到e
具有最大节点数的路径,使得:
- 总距离小于某个常数
d
- 从 s 开始,路径中的每个节点都比前一个节点更靠近节点
e
。(例如,当您遍历路径时,您将越来越接近目的地e
。就剩余路径的边缘权重而言。)
我们可以假设图中没有循环。没有负权重。这个问题是否已经存在有效的算法?这个问题有名字吗?
无论你最终做什么,从头开始做一个 BFS/DFS s
,看看是否e
可以达到;这只需要你 O(n+m) 所以它不会增加问题的复杂性(因为你无论如何都需要查看所有顶点和边)。0
此外,在你做任何其他事情之前删除所有带有权重的边,因为这些边永远不会满足你的第二个标准。
编辑:我想出了一个算法;它是多项式的,具体取决于图表的大小,它可能仍然不够有效。请参阅下面的编辑。
现在介绍一些复杂性。这里首先要考虑的是我们实际上可以拥有多少条路径的上限,因此根据d
边缘的选择和权重,我们对任何潜在算法的复杂度也有一个上限。
DAG 中可以有多少条边?答案是n(n-1)/2
,这是一个紧密的界限:取n
顶点,从 1 到n
; 对于两个顶点i
和j
,将边添加i->j
到图 iff i<j
。这总和为n(n-1)/2
,因为这样一来,对于每一对顶点,它们之间恰好有一个有向边,这意味着我们在图中的边数与在n
顶点上的完整无向图中的边数一样多。
在上面描述的图中,从一个顶点到另一个顶点可以有多少条路径?答案是 2 n-2。归纳证明:
如上所述,取超过 2 个顶点的图;从顶点 1 到顶点 2有 1 = 2 0 = 2 2-2路径:(1->2)。
归纳步骤:假设有 2 n-2条路径从上面描述的顶点图编号1
的顶点到编号为的顶点,增加每个顶点的数量并添加一个新顶点以及所需的边。它对现在标记为 的顶点有自己的边。此外,对于 [2;n] 中的每个,它都有 2 i-2条到该顶点的路径(它具有其他顶点到顶点的所有路径,每个路径都以 edge 为“前缀” )。这给了我们 1 + Σ nn
n
1
n
n+1
i
n+1
1->i
k=2 (2 k-2 ) = 1 + Σ n-2 k=0 (2 k-2 ) = 1 + (2 n-1 - 1) = 2 n-1 = 2 (n+1)-2 .
所以我们看到有一些 DAG在它们的一些顶点对之间有 2 n-2条不同的路径;这是一个有点黯淡的前景,因为根据权重和您的选择d
,您可能必须考虑所有因素。这本身并不意味着我们不能有效地选择某种形式的最优(这是你正在寻找的)。
编辑:好的,这就是我要做的:
现在这给了你 O(n^3) 的空间复杂度和 O(n²m) 的时间复杂度 - 数组有 O(n²) 项,我们必须迭代 O(m) 数组,每个边一个数组 -但我认为很明显,可以使用散列结构和数组以外的其他东西来优化这里对数据结构的浪费使用。或者你可以只使用一个一维数组并且只存储当前最小值而不是每次都重新计算它(你必须将路径的边权重之和与前一个顶点一起封装,因为你需要知道前一个顶点重建路径),这会将数组的大小从 n² 更改为 n,因为现在每个路径到顶点的节点数只需要一个条目,从而将算法的空间复杂度降低到 O (n²) 和 O(nm) 的时间复杂度。e
,因为这些也可以安全地忽略。