【问题标题】:Dijktra's-How to keep track of nodes in the shortest path from source to the targetDijktra's-如何跟踪从源到目标的最短路径中的节点
【发布时间】:2015-05-23 13:36:53
【问题描述】:

昨天我研究了 Dijktra 的算法以找到最短路径。我尝试了一些问题,以便我可以对它进行一些命令。但是我遇到了这个问题 ,它被要求找到最短的节点从源到目标的路径,如果它们是从源到目标的路径,则打印“不可能”。即使经过深思熟虑,我也无法解决这个问题。有人可以帮忙吗?

【问题讨论】:

  • 如果你想了很多,你一定有一些想法。带他们。您还将此标记为“C++”。你有一些代码吗?
  • @Mads 看我听起来可能完全是垃圾,但我认为最好的办法是保持向量。

标签: c++ dijkstra


【解决方案1】:

Djikstra 的算法在概念上可能看起来易于理解,但要实施需要相当大的努力。您需要一个数据结构,例如 Priority queue 来有效地存储和检索权重最低的节点。该算法是贪心算法概念的BFS导数。

我使用 C++ STL 设置数据结构 代替了优先级队列来存储具有最小权重的节点(查看此设置数据结构详细信息http://www.cplusplus.com/reference/set/set/set/)。

请记住,此代码仅适用于权重为正的边。 对于权重为负的边,您需要学习 Bellman-Ford 算法

程序代码:

#include<set>
#include<iostream>
#include<stdlib>
#include<vector>
#define INF 9999999

using namespace std;

struct vw{
    int index;
    bool visited=false;
    int w=INF;
};
int adj[10][10], v, e, visited[10];

class comparisonClass{
public:
    bool operator()(struct vw a, struct vw b){
        return (a.w < b.w);
    }
};

int main(){
    cin>>v>>e;                              
    // Enter the number of edges & vertices.
    struct vw *vertex = new struct vw[v];
    for(int i=0; i<e; i++){
        char a, b;                          
        int w;
        cin>>a>>b>>w;                       
        // Enter egde and weights: Eg- A B 5  B D 20
        cout<<a<<" "<<b<<" "<<w<<endl;
        adj[a-65][b-65]=adj[b-65][a-65]=w;
        vertex[i].index=i;
    }
    set<struct vw, comparisonClass> weightList;
    vertex[0].w=0;  vertex[0].visited=true;
    weightList.insert(vertex[0]);

    while(!weightList.empty()){
        struct vw source = *(weightList.begin());
        weightList.erase(weightList.begin());
        int ind = source.index;
        source.visited=true;

        for(int i=0; i<v; i++){
            if(adj[ind][i] && vertex[i].visited==false)
                if(adj[ind][i]+source.w < vertex[i].w){
                    vertex[i].w = adj[ind][i] + source.w;
                    weightList.insert(vertex[i]);
                }
        }
    }

    for(int i=0; i<v; i++)
        cout<<"\nA to "<<(char)(65+i)<<" cost="<<vertex[i].w<<endl; 
        // Printed results in format of Edges and least weight, Eg- A to D cost = 12.
    delete[]vertex;
    return 0;
}

【讨论】:

    【解决方案2】:

    很简单,看Wikipedia page有伪代码

     1  function Dijkstra(Graph, source):
     2
     3      dist[source] ← 0                       // Distance from source to source
     4      prev[source] ← undefined               // Previous node in optimal path initialization
     5
     6      for each vertex v in Graph:  // Initialization
     7          if v ≠ source            // Where v has not yet been removed from Q (unvisited nodes)
     8              dist[v] ← infinity             // Unknown distance function from source to v
     9              prev[v] ← undefined            // Previous node in optimal path from source
    10          end if 
    11          add v to Q                     // All nodes initially in Q (unvisited nodes)
    12      end for
    13      
    14      while Q is not empty:
    15          u ← vertex in Q with min dist[u]  // Source node in first case
    16          remove u from Q 
    17          
    18          for each neighbor v of u:           // where v is still in Q.
    19              alt ← dist[u] + length(u, v)
    20              if alt < dist[v]:               // A shorter path to v has been found
    21                  dist[v] ← alt 
    22                  prev[v] ← u 
    23              end if
    24          end for
    25      end while
    26
    27      return dist[], prev[]
    28
    29  end function
    

    如果我们只对顶点源和目标之间的最短路径感兴趣,如果 u = target,我们可以在第 15 行之后终止搜索。现在我们可以通过反向迭代读取从源到目标的最短路径:

    1  S ← empty sequence
    2  u ← target
    3  while prev[u] is defined:                 // Construct the shortest path with a stack S
    4      insert u at the beginning of S          // Push the vertex onto the stack
    5      u ← prev[u]                             // Traverse from target to source
    6  end while
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-11
      相关资源
      最近更新 更多