数学:Dijkstra算法

 

一.最短路径的最优子结构性质

   该性质描述为:如果P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径,k和s是这条路径上的一个中间顶点,那么P(k,s)必定是从k到s的最短路径。下面证明该性质的正确性。

   假设P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径,则有P(i,j)=P(i,k)+P(k,s)+P(s,j)。而P(k,s)不是从k到s的最短距离,那么必定存在另一条从k到s的最短路径P'(k,s),那么P'(i,j)=P(i,k)+P'(k,s)+P(s,j)<P(i,j)。则与P(i,j)是从i到j的最短路径相矛盾。因此该性质得证。

 

二. Dijkstra算法

    Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。

 

先给出一个无向图

数学:Dijkstra算法

用Dijkstra算法找出以A为起点的单源最短路径步骤如下

数学:Dijkstra算法

 

三. 代码

Java

static int[] testDijkstra(int n,int v,int[] dist,int[] prev,int[][] c){
  
  int maxnum = 100;
  int maxint = 999999;
  
  boolean[] s = new boolean[maxnum];    // 判断是否已存入该点到S集合中
  for(int i=1; i<=n; ++i)
  {
   dist[i] = c[v][i];
   s[i] = false;     // 初始都未用过该点
   if(dist[i] == maxint)
    prev[i] = 0;
   else
    prev[i] = v;
  }
  dist[v] = 0;
  s[v] = true;
  
  // 依次将未放入S集合的结点中,取dist[]最小值的结点,放入结合S中
  // 一旦S包含了所有V中顶点,dist就记录了从源点到所有其他顶点之间的最短路径长度
          // 注意是从第二个节点开始,第一个为源点
  for(int i=2; i<=n; ++i)
  {
   int tmp = maxint;
   int u = v;
   // 找出当前未使用的点j的dist[j]最小值
   for(int j=1; j<=n; ++j)
    if((!s[j]) && dist[j]<tmp)
    {
     u = j;              // u保存当前邻接点中距离最小的点的号码
     tmp = dist[j];
    }
   s[u] = true;    // 表示u点已存入S集合中
  
   // 更新dist
   for(int j=1; j<=n; ++j)
    if((!s[j]) && c[u][j]<maxint)
    {
     int newdist = dist[u] + c[u][j];
     if(newdist < dist[j])
     {
      dist[j] = newdist;
      prev[j] = u;
     }
    }
  }
  
  return dist;
 }

 

 

你可能感兴趣的:(数学:Dijkstra算法)