迪杰特斯拉算法: 按最短路径长度由小到大的顺序,逐步求得每一条最短路径.

来源:互联网 发布:单片机51 编辑:程序博客网 时间:2024/06/05 02:48

//迪杰特斯拉算法: 按最短路径长度由小到大的顺序,逐步求得每一条最短路径.
//有下面几个假设:
//1 n个顶点的有向网络用adjmatrix表示,其存储结构已建立.
//2 把网络中的所有顶点分成两个部分: 1 源点到他们的最短路径已经最终确定的. 2 源点到他们的最短路径还没有确定.
//有3个辅助数组
// dist[i] : Vx->Vi的"当前最短的"路径的长度
// path[i] : Vx->Vi的"当前最短的"路径上倒数第二个顶点的序号
// mark[i] : 1 : Vx->Vi 的最短路径已经确定,Vi进入第一组
//           0 : Vx->Vi 的最短路径没有确定,Vi还在第二组

//算法思路: 
//1 初始化: 第一组中只有Vx,其他节点都在第二组,3个辅助数组的初始化
// mark[x] = 1 ;//进入点是x
// 对于所有的i(i!=x), mark[i] = 0;//表示没有进入第一组
// 对于所有的i,令dist[i] = Wxi,path[i] = x;
//2 从第二组的顶点中,选一个距离源点Vx最近的顶点Vk,将Vk加入到第一组.
//  检查第二组中其余顶点距离Vx的长度,若Vk加入到第一组后,可以使长度变短,就修正.

void dijkstra(int x)
{//进入点是x
 int i;  //index而已
 int j;
 int k;
 int path[n0+1];//到结果的前一个节点的位置
 int mark[n0+1]; //0不确定,1确定
 float min;      //目前最短的路径
 float dist[n0+1]; //i到x的目前的最短路径

 //初始化
 for(i=1;i<=n;i++)
 {
  mark[i] = 0;
  dist[i] = adjmatrix[x][i];
  path[i] = x;
 }
 mark[x]=1; //x已经在第一组
 do
 {
  min = infinity;
  k=0;
  for(i=1;i<=n;i++)
  {
   if((mark[i]==0)&&(dist[i]<min))
   {//如果它的路径比min小,并且这个节点还没有进第一组,就替换min和index
    min = dist[i];
    k = i;//目前最小的距离的点的位置,也就是要加入到第一组的点的位置
   }
  }
  if(k)
  {//如果找到了这样的点,就是k!=0
   mark[k]=1; //把k点加入到第一组
   //修改其他的路径
   for(i=1;i<=n;i++)
   {
    if(dist[i]>(min+adjmatrix[k][i]))
    {//min:已经确定的Vx->Vk的最短距离, 就是说:  如果 目前Vx->Vi 的最短距离比 Vx->Vk的最短距离+(Vk,Vi),那么换路径好了,走k节点到i
     dist[i] = min+adjmatrix[k][i];
     path[i] = k;
    }
   }
  }

 } while (k); //当k为0时候说明,dijkstra算法结束

 //现在输出
 for(i=1;i<=n;i++)
 {
  if((i!=k)&&(dist[i]<infinity))
  {//i!=k : 本身路径不用输出, dist[i]<infinity : 这个点是可达的
   k = i;
   do
   {
    cout<<k<<"--";
    k = path[k]; //找前一个节点
   } while (k!=x); //当找到源头的时候,这个路径得到
   cout<<x<<endl;
   cout<<"value : "<<dist[i]<<endl;
  }
 }

}

原创粉丝点击