简体   繁体   English

如何在DAG中找到两个顶点之间的最大权重路径?

[英]How to find the maximum-weight path between two vertices in a DAG?

In a DAG G, with non negative weighted edges, how do you find the maximum-weight path between two vertices in G? 在具有非负加权边的DAG G中,如何找到G中两个顶点之间的最大权重路径?

Thank you guys! 感谢大伙们!

You can solve this in O(n + m) time (where n is the number of nodes and m the number of edges) using a topological sort. 您可以使用拓扑排序在O(n + m)的时间内(其中n是节点数,m是边数)求解。 Begin by doing topological sort on the reverse graph, so that you have all the nodes ordered in a way such that no node is visited before all its children are visited. 首先在反向图上进行拓扑排序,以便对所有节点进行排序,以便在访问所有子节点之前不访问任何节点。

Now, we're going to label all the nodes with the weight of the highest-weight path starting with that node. 现在,我们将使用从该节点开始的最高权重路径的权重来标记所有节点。 This is done based on the following recursive observation: 这是基于以下递归观察完成的:

  • The weight of the highest-weight path starting from a sink node (any node with no outgoing edges) is zero, since the only path starting from that node is the length-zero path of just that node. 从宿节点(无出站边缘的任何节点)开始的最高权重路径的权重为零,因为从该节点开始的唯一路径是该节点的零长度路径。
  • The weight of the highest-weight path starting from any other node is given by the maximum weight of any path formed by following an outgoing edge to a node, then taking the maximum-weight path from that node. 从任何其他节点开始的最高权重路径的权重由以下任何路径的最大权重给出:通过遵循出站边沿到达节点,然后从该节点取最大权重路径。

Because we have the nodes reverse-topologically sorted, we can visit all of the nodes in an order that guarantees that if we ever try following an edge and looking up the cost of the heaviest path at the endpoint of that node, we will have already computed the maximum-weight path starting at that node. 因为我们对节点进行了反向拓扑排序,所以我们可以按顺序访问所有节点,以确保如果我们尝试沿着边缘并在该节点的端点处查找最重路径的成本,那么我们已经计算从该节点开始的最大权重路径。 This means that once we have the reverse topological sorted order, we can apply the following algorithm to all the nodes in that order: 这意味着一旦获得了反向拓扑排序的顺序,便可以将以下算法应用于该顺序的所有节点:

  1. If the node has no outgoing edges, record the weight of the heaviest path starting at that node (denoted d(u)) as zero. 如果该节点没有输出边缘,则记录从该节点开始的最重路径的权重(表示为d(u))为零。
  2. Otherwise, for each edge (u, v) leaving the current node u, compute l(u, v) + d(v), and set d(u) to be the largest value attained this way. 否则,对于离开当前节点u的每个边(u,v),计算l(u,v)+ d(v),并将d(u)设置为以此方式获得的最大值。

Once we've done this step, we can make one last pass over all the nodes and return the highest value of d attained by any node. 完成此步骤后,我们可以在所有节点上进行最后一次传递,并返回任何节点获得的d的最大值。

The runtime of this algorithm can be analyzed as follows. 可以如下分析该算法的运行时间。 Computing a topological sort can be done in O(n + m) time using many different methods. 可以使用许多不同的方法在O(n + m)时间内完成拓扑排序的计算。 When we then scan over each node and each outgoing edge from each node, we visit each node and edge exactly once. 然后,当我们扫描每个节点和每个节点的每个传出边缘时,我们将访问每个节点和边缘一次。 This means that we spend O(n) time on the nodes and O(m) time on the edges. 这意味着我们在节点上花费O(n)时间,在边缘上花费O(m)时间。 Finally, we spend O(n) time on one final pass over the elements to find the highest weight path, which takes O(n). 最后,我们在元素的最后一次传递上花费O(n)时间,以找到最高权重路径,该路径花费了O(n)。 This gives a grand total of O(n + m) time, which is linear in the size of the input. 这样得出的总时间为O(n + m),这在输入大小上是线性的。

A simple brute-force algorithm can be written using recursive functions. 可以使用递归函数编写一个简单的蛮力算法。 Start with an empty vector (in C++: std::vector) and insert the first node. 从一个空向量开始(在C ++中:std :: vector)并插入第一个节点。 Then call your recursive function with the vector as argument that does the following: 然后使用vector作为参数调用递归函数,该函数将执行以下操作:

  • loop over all neighbours and for each neighbour 遍历所有邻居,并遍历每个邻居
    • copy the vector 复制向量
    • add the neighbour 添加邻居
    • call ourself 自称

Also add the total weight as argument to the recursive function and add the weight in every recursive call. 还将总权重作为参数添加到递归函数,并在每次递归调用中添加权重。

The function should stop whenever it reaches the end node. 该函数应在到达末端节点时停止。 Then compare the total weight with the maximum weight you have so far (use a global variable) and if the new total weight is bigger, set the maximum weight and store the vector. 然后将总重量与您到目前为止拥有的最大重量(使用全局变量)进行比较,如果新的总重量更大,则设置最大重量并存储矢量。

The rest is up to you. 其余的取决于您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM