Single-Source Shortest Paths – Dijkstra’s Algorithm

来源:互联网 发布:ios10蜂窝移动数据设置 编辑:程序博客网 时间:2024/05/23 00:59

在加权图中给出一组源顶点V的源顶点,其中所有边缘权重w(u,v)都是非负的,从给定源s找到所有顶点的最短路径权重d(s,v)v存在于图表中。

例如,

从顶点A到顶点B的路径的最小成本为4,路线为 - A E B

从顶点A到顶点C的路径的最小成本为6,路线为 - A E B C

从顶点A到顶点D的路径的最小成本为5,路线为 - A E D

从顶点A到顶点E的路径的最小成本为3,路线为 - A E

dijkstras-7

我们知道,广度优先搜索可以用于在未加权图中找到最短路径,或者甚至在具有相同成本的所有边缘的加权图中。但是,如果图中的边缘以不同的成本加权,则BFS将推广到统一成本搜索。现在,统一成本搜索不是根据根深度的顺序来扩展节点,而是按照根节点的成本顺序来扩展节点。该算法的一个变体称为Dijkstra算法。

Dijkstra算法是一种用于查找图中节点间最短路径的算法。对于图中的给定源节点,算法找到该节点和每个其他节点之间的最短路径。一旦确定到目的地节点的最短路径,它也可以用于通过停止算法来找到从单个节点到单个目的地节点的最短路径。

Dijkstra的算法是基于松弛的原理,其中对正确距离的近似逐渐被更准确的值代替,直到达到最短距离。每个顶点的近似距离总是对真实距离进行过高估计,并由其旧值的最小值替换为新找到的路径的长度。它使用优先级队列贪婪地选择尚未处理的最接近的顶点,并在其所有出口边缘上执行此松弛过程。

以下是根据维基百科的Dijkstra算法的psedocode。

function Dijkstra(Graph, source)    dist[source] = 0    // Initialization    create vertex set Q    for each vertex v in Graph    {        if v != source        {            dist[v] = INFINITY        // Unknown distance from source to v            prev[v] = UNDEFINED       // Predecessor of v        }        Q.add_with_priority(v, dist[v])    }    while Q is not empty    {        u = Q.extract_min()            // Remove minimum        for each neighbor v of u that is still in Q        {            alt = dist[u] + length(u, v)            if alt < dist[v]             {                dist[v] = alt                prev[v] = u                Q.decrease_priority(v, alt)            }        }    }    return dist[], prev[]

例如,考虑下图。我们将从顶点A开始。因此顶点A具有距离0,剩余的顶点距离源具有未定义(无限)的距离。令S是已经计算出与源的最短路径距离的顶点集合。

dijkstras-1

最初S = {},我们将源顶点推到它。 S = {A}。
我们从源顶点A开始,开始放松A的邻居。由于可以从顶点A的直接边缘到达顶点B,所以我们将其距离更新为10(边缘A-B的权重)。类似的顶点E可以通过从A的直接边到达,所以我们更新其从无穷远到3的距离。

dijkstras-2

在处理A的所有出局边缘之后,我们接下来考虑具有最小距离的顶点。 B的距离为10,E具有距离3,所有剩余的顶点具有距离无穷大。所以我们选择E并将其推入Set S.现在我们的集合变成S = {A,E}。接下来我们放松E的邻居。 E有2个邻居B和C.我们已经找到一个通过顶点A的路线到顶点B,其成本为10。但是如果我们通过顶点E访问顶点B,我们将获得更便宜的路由。即边缘A-E +边缘E-B成本的成本= 3 + 1 = 4 <10(边缘A-B的成本)。

dijkstras-3

我们重复这个过程,直到我们处理了所有的顶点。即Set S变满了

dijkstras-4

dijkstras-5

dijkstras -6-

dijkstras-7

C ++

#include<bits/stdc++.h>using namespace std;//图中的节点数#define N 5//数据结构存储图形边struct Edge {    int source, dest, weight;};//类来表示一个图形对象class Graph{    public:     //表示相邻列表的向量数组    vector<Edge> adjList[N];    Graph(vector<Edge> edges)    {          //将边缘添加到无向图        for (unsigned i = 0; i < edges.size(); i++)        {            int source = edges[i].source;            int dest = edges[i].dest;            int weight = edges[i].weight;            //在末尾插入            adjList[source].push_back({source, dest, weight});        }    }};//存储堆节点的数据结构struct Node {    int vertex, weight;};void printRoute(int prev[], int i){    if (i < 0)        return;    printRoute(prev, prev[i]);    cout << i << " ";}//用于排序堆的比较对象struct comp {    bool operator()(const Node lhs, const Node rhs) const    {        return lhs.weight > rhs.weight;    }};//在给定图上运行Dijkstra算法void shortestPath(Graph const& graph, int source){     //创建最小堆并推送距离为0的源节点    priority_queue<Node, vector<Node>, comp> minHeap;        minHeap.push({source, 0});   //将源的无限距离设置为v    vector<int> dist(N, INT_MAX);    //从源到本身的距离为零    dist[source] = 0;    bool done[N] = {0};    done[0] = 1;    //布尔数组来跟踪已经找到最小成本的顶点    int prev[N] = {-1};    // run till minHeap is not empty    while (!minHeap.empty())    {        //删除并返回最佳顶点        Node node = minHeap.top();        minHeap.pop();       //获取顶点数        int u = node.vertex;         //为你的每个邻居v做        for (auto i : graph.adjList[u])        {            int v = i.dest;            int weight = i.weight;            // Relaxation step            if (!done[v] && (dist[u] + weight) < dist[v])            {                dist[v] = dist[u] + weight;                prev[v] = u;                minHeap.push({v, dist[v]});            }        }        //标记的顶点u完成,所以它不会再被拾起        done[u] = 1;    }    for (int i = 1; i < N; ++i)    {        cout << "Path from vertex 0 to vertex " << i << " has minimum "                "cost of " << dist[i] << " and the route is - ";        printRoute(prev, i);        cout << endl;    }}// 主函数int main(){    // initalize edges as per above diagram    vector<Edge> edges =     {        {0, 1, 10}, {0, 4, 3}, {1, 2, 2}, {1, 4, 4}, {2, 3, 9},         {3, 2, 7}, {4, 1, 1}, {4, 2, 8}, {4, 3, 2}    };    // construct graph    Graph graph(edges);    shortestPath(graph, 0);    return 0;}Output: Path from vertex 0 to vertex 1 has minimum cost of 4 and the route is – 0 4 1Path from vertex 0 to vertex 2 has minimum cost of 6 and the route is – 0 4 1 2Path from vertex 0 to vertex 3 has minimum cost of 5 and the route is – 0 4 3Path from vertex 0 to vertex 4 has minimum cost of 3 and the route is – 0 4
阅读全文
0 0
原创粉丝点击