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

📅  最后修改于: 2021-04-22 01:52:37             🧑  作者: Mango

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

图形

实际应用示例:
这个问题是Dijkstra算法的一个著名变体。在实际应用中,此问题可以看作是带有路由器的图形,因为其顶点和边表示两个顶点之间的带宽。现在,如果我们要查找Internet连接中两个位置之间的最大带宽路径,则可以通过此算法解决此问题。
如何解决这个问题呢?
我们将通过使用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 prthe 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