📜  最宽路径问题 | Dijkstra算法的实际应用

📅  最后修改于: 2021-10-25 05:14:45             🧑  作者: Mango

强烈建议首先阅读使用优先队列的 Dijkstra 算法。
最宽路径问题是在图的两个顶点之间找到一条路径的问题,使路径中的最小权重边的权重最大化。请参阅下图以了解问题所在:

图形

实际应用示例:
这个问题是 Dijkstra 算法的一个著名变体。在实际应用中,这个问题可以看成一个以路由器为顶点的图,边代表两个顶点之间的带宽。现在如果我们想在互联网连接中找到两个地方之间的最大带宽路径,那么这个问题可以通过这个算法来解决。
如何解决这个问题呢?
我们将通过使用 Dijkstra 算法的优先级队列 ((|E|+|V|)log|V|) 来解决这个问题,并稍作改动。
我们通过将 Dijkstra 算法中的松弛条件替换为:

其中 u 是 v 的源顶点。 v 是我们正在检查条件的当前顶点。
该算法适用于有向图和无向图。
请参阅下面的一系列图像以了解问题和算法:
边上的值表示有向边的权重。

有向无环图

我们将从源顶点开始,然后遍历与其相连的所有顶点,并根据松弛条件加入优先队列。

现在 (2, 1) 将弹出并且 2 将是当前的源顶点。

现在 (3, 1) 将从队列中弹出。但是由于 3 没有任何通过有向边连接的顶点,所以什么都不会发生。所以 (4, 2) 接下来会弹出。

最后算法停止,因为优先级队列中没有更多元素。

最宽距离最大值的路径是 1-4-3,最大瓶颈值为 2。所以我们最终得到最宽距离 2 以到达目标顶点 3。
下面是上述方法的实现:

CPP
// C++ implementation of the approach
#include 
using namespace std;
 
// Function to print the required path
void printpath(vector& parent, int vertex, int target)
{
    if (vertex == 0) {
        return;
    }
 
    printpath(parent, parent[vertex], target);
 
    cout << vertex << (vertex == target ? "\n" : "--");
}
 
// Function to return the maximum weight
// in the widest path of the given graph
int widest_path_problem(vector > >& Graph,
                        int src, int target)
{
    // To keep track of widest distance
    vector widest(Graph.size(), INT_MIN);
 
    // To get the path at the end of the algorithm
    vector parent(Graph.size(), 0);
 
    // Use of Minimum Priority Queue to keep track minimum
    // widest distance vertex so far in the algorithm
    priority_queue, vector >,
                   greater > >
        container;
 
    container.push(make_pair(0, src));
 
    widest[src] = INT_MAX;
 
    while (container.empty() == false) {
        pair temp = container.top();
 
        int current_src = temp.second;
 
        container.pop();
 
        for (auto vertex : Graph[current_src]) {
 
            // Finding the widest distance to the vertex
            // using current_source vertex's widest distance
            // and its widest distance so far
            int distance = max(widest[vertex.second],
                               min(widest[current_src], vertex.first));
 
            // Relaxation of edge and adding into Priority Queue
            if (distance > widest[vertex.second]) {
 
                // Updating bottle-neck distance
                widest[vertex.second] = distance;
 
                // To keep track of parent
                parent[vertex.second] = current_src;
 
                // Adding the relaxed edge in the prority queue
                container.push(make_pair(distance, vertex.second));
            }
        }
    }
 
    printpath(parent, target, target);
 
    return widest[target];
}
 
// Driver code
int main()
{
 
    // Graph representation
    vector > > graph;
 
    int no_vertices = 4;
 
    graph.assign(no_vertices + 1, vector >());
 
    // Adding edges to graph
 
    // Resulting graph
    // 1--2
    // |  |
    // 4--3
 
    // Note that order in pair is (distance, vertex)
    graph[1].push_back(make_pair(1, 2));
    graph[1].push_back(make_pair(2, 4));
    graph[2].push_back(make_pair(3, 3));
    graph[4].push_back(make_pair(5, 3));
 
    cout << widest_path_problem(graph, 1, 3);
 
    return 0;
}


Python3
# Python3 implementation of the approach
 
# Function to print required path
def printpath(parent, vertex, target):
     
    # global parent
    if (vertex == 0):
        return
    printpath(parent, parent[vertex], target)
    print(vertex ,end="\n" if (vertex == target) else "--")
 
# Function to return the maximum weight
# in the widest path of the given graph
def widest_path_problem(Graph, src, target):
     
    # To keep track of widest distance
    widest = [-10**9]*(len(Graph))
 
    # To get the path at the end of the algorithm
    parent = [0]*len(Graph)
 
    # Use of Minimum Priority Queue to keep track minimum
    # widest distance vertex so far in the algorithm
    container = []
    container.append((0, src))
    widest[src] = 10**9
    container = sorted(container)
    while (len(container)>0):
        temp = container[-1]
        current_src = temp[1]
        del container[-1]
        for vertex in Graph[current_src]:
 
            # Finding the widest distance to the vertex
            # using current_source vertex's widest distance
            # and its widest distance so far
            distance = max(widest[vertex[1]],
                           min(widest[current_src], vertex[0]))
 
            # Relaxation of edge and adding into Priority Queue
            if (distance > widest[vertex[1]]):
 
                # Updating bottle-neck distance
                widest[vertex[1]] = distance
 
                # To keep track of parent
                parent[vertex[1]] = current_src
 
                # Adding the relaxed edge in the prority queue
                container.append((distance, vertex[1]))
                container = sorted(container)
    printpath(parent, target, target)
    return widest[target]
 
# Driver code
if __name__ == '__main__':
 
    # Graph representation
    graph = [[] for i in range(5)]
    no_vertices = 4
    # Adding edges to graph
 
    # Resulting graph
    #1--2
    #|  |
    #4--3
 
    # Note that order in pair is (distance, vertex)
    graph[1].append((1, 2))
    graph[1].append((2, 4))
    graph[2].append((3, 3))
    graph[4].append((5, 3))
 
    print(widest_path_problem(graph, 1, 3))
 
# This code is contributed by mohit kumar 29


输出:
1--4--3
2

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。