需要帮助来了解Dijkstra的算法

时间:2018-11-29 03:55:12

标签: c++ data-structures dijkstra

我正在尝试遵循Dijkstra算法的伪代码,但我不了解它如何为我提供最短的路径。遵循以下伪代码:

DijkstrasAlgorithm(G, w, s)
    InitalizeSingleSource(G, s)
    S = 0
    Q = G.V
    while Q != 0
        u = ExtractMin(Q)
        S = S∪{u}
        for each vertex v ∈ G.Adj[u]
            Relax(u, v, w)

这是我最终得到的代码:

DijkstrasAlgorithm(string w, string s) {
    string u;
    string s;
    InitalizeSingleSource(s);
    for (map<string, Vertex*>::iterator it = vertices.begin(); 
    it!=vertices.end(); ++it) {
        minQ.insert(it->first, it->second->key);
    }
    while (u != "empty") {
        u = minQ.extractMin();
        if (!s.empty()) {
            s.append("->");
        }
        s.append(u);
        vector<Neighbor*>::iterator it = adjList[u].begin();
        while (it != adjList[u].end()) {
            relax(u, w, (*it)->weight);
            it++;
        }
    }
    return s;
}

问题是,这段代码并没有给我最短的路径。看着伪代码,我不知道怎么回事。假设我有5个顶点(a,b,c,d和e),那么我想找到从a到c的最短路径,而最短的路径是a-> b-> c。这些代码所要做的就是给我提供c-> e-> d-> b-> a。

我只是不了解这里的逻辑。我们使用InitalizeSingleSource(s)将顶点的所有键值初始化为INT_MAX,但s除外,s为0。从这里,我们找到顶点键值的最小值,而不是使用adjList。

当minQ为空时,我们停止而不是到达路径的末尾。所有这些操作是打印所有顶点而不是最短路径。最重要的是,我们将大多数键设置为INT_MAX,因此找到它们之间的最小值会感到多余。

完成后,即使没有在最小路径测量中使用边缘,我们也都使用了G.E / G.Adj [u]放松函数。

很多事情对我来说没有意义,但我认为最奇怪的部分是根据顶点(G.V)而不是边缘(G.E)设置Q / minQ。应该如何找到最小路径?谁能解释我不理解的算法伪代码的哪一部分?谢谢!

编辑:也包括“放松”功能。

relax(string u, string v, int weight) {
    if (vertices[v]->key > (vertices[u]->key + weight)) { 
        vertices[v]->key = (vertices[u]->key + weight);
        vertices[v]->pi = new std::string(u);
    }
}

1 个答案:

答案 0 :(得分:0)

放松会降低minQ中的值。

第一个提取的节点是源,因为0

现在,已将与源相邻的所有顶点标记为已经找到的最短路径。

然后,经过处理的顶点之一的minQ值最低,然后将其提取并进行处理。

现在您应该能够看到此提取->松弛周期如何在图形中显示每个节点都标有达到该目标的最低成本的图形。

如果每次放松时都更新指向“放松源”节点的指针,则可以从所需的目标节点向后走以读取最短路径。