单源点最短路径(dijkstra算法)

1.  最短路径的描述

     给出有向图G,它的每条边都有一个非负的长度(耗费)a[i][j],路径的长度即为此路径所经过的边的长度之和。对于给定的源顶点s,需找出从它到图中其他任意顶点(称为目的)的最短路径。

2.  生成最短路径的贪心算法

    利用E. Dijkstra发明的贪心算法可以解决最短路径问题,它通过分步方法求出最短路径。每一步产生一个到达新的目的顶点的最短路径。下一步所能达到的目的顶点通过如下贪心准则选取:在还未产生最短路径的顶点中,选择路径长度最短的目的顶点。也就是说, Dijkstra的方法按路径长度顺序产生最短路径。 首先最初产生从s到它自身的路径,这条路径没有边,其长度为0。在贪婪算法的每一步中,产生下一个最短路径。方法是在目前产生的每一条最短路径中,考虑加入一条最短的边,再从所有这些边中先选择最短的,这种策略即是Dijkstra算法。

              procedure  SHORTEST-PATHSvCOSTDISTn

                   //G是一个n结点有向图,他由其成本领接矩阵COSTnn)表示DISTj)被置以节电v到节电j的最短路径长度,这里1jnDISTv)被置成零。//

                    boolean  S1n);real  COST1n1n),DIST1n

                    integer  uvnnumiw

                    for  i 1  to  n  do   //将集合S初始化为空//

                        Si 0DISTi COSTvi

                    repeat

                    Sv 1DISTv 0   //结点v计入S//

                    for  num 2  to  n-1  do  //确定由结点v出发的n-1条路//

                       选取结点u,它使得DISTu=

                       Su 1  //结点u计入S//

                       for   所有Sw=0的结点w  do  //修改距离//

                         DISTw minDISTw),DISTu+COSTuw))

                       repeat

                    repeat

              end  SHORTEST-PATHS

2. 问题描述

    在下图的有向图中(这里用任两点间的距离矩阵表示),利用算法SHORTEST-PATHS获取按长度非降次序排列的由结点1到其余结点最短路径长度。

 -1,-1,15,-1,-1,-1 //定义距离数组,-1表示不可到达
 2,-1,-1,-1,10,30
 -1,4,-1,-1,-1,10
 -1,-1,-1,-1,-1,-1
 -1,-1,-1,15,-1,-1
 -1,-1,-1,4,10,-1

3. 程序清单

 /**单源点最短路径问题
 * ShortestPath2.java
 */
package com.algorithm.knapsack;
public class ShortestPath2 {
static int SIZE = 6;
static int INF = Integer.MAX_VALUE;
public static void dijkstra(int v,int[][] cost,int[] dist){
 int n=dist.length;
 //System.out.println(n);
 boolean[] s=new boolean[n];
    for(int i=0;i<n;i++)  //dist[]数组初始化为点v到各点的初始距离
    {
     dist[i] = cost[v][i];   
     s[i] = false;       //将集合s初始化为false
    }
    dist[v]=0;s[v]=true;  //结点v计入s
    for(int i=0;i<n;i++) 
    {
       int temp = Integer.MAX_VALUE;  
     int u=v;
     for(int j=0;j<n;j++)
      if(!s[j]&&(dist[j]<temp))  //找到还没被放入到s中的点
      {
       u = j;
       temp =dist[j];
      }
     s[u] = true;
     for(int j=0;j<n;j++)
      if(!s[j]&&(cost[u][j]<Integer.MAX_VALUE))
      {
       int newDistance = dist[u]+cost[u][j];   //修改距离
       if(newDistance<dist[j])         //如果新的距离比原有距离短,则修改
        dist[j] = newDistance;
      }
    }
}
public static void main(String[] args){
 int dist[] = new int[SIZE];
 int cost[][] = {{INF,INF,15,INF,INF,INF}, //定义距离数组,INF表示不可到达
         {2,INF,INF,INF,10,30},
         {INF,4,INF,INF,INF,10},
         {INF,INF,INF,INF,INF,INF},
         {INF,INF,INF,15,INF,INF},
         {INF,INF,INF,4,10,INF}};
 int v=0; //从图中的结点1开始
 int[] index = new int[6];
 dijkstra(v,cost,dist); //调用dijkstra方法求v到其它结点的距离
 for(int i=0;i<dist.length;i++)
  index[i]=i;
 for(int i=0;i<dist.length-1;i++)
 { 
   for(int j=i+1;j<dist.length;j++)
  {
   if(dist[i]>dist[j])       //对求得路径数组进行排序
   {
   int  temp = dist[i];  
    dist[i] = dist[j];
    dist[j] = temp;
    int x=index[i];       //交换相应的数组下标
    index[i] = index[j];
     index[j] = x;               
   }
   }
 }
 for(int i=1;i<6;i++)
  System.out.println("从结点1到结点"+(index[i]+1)+"的最短距离是:"+dist[i]);
}
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值