单源最短路径
给定带权有向网络G=(V,E,W),每条边 e=<i,j>的权w(e)为非负实数,表示从i到j的距离。源点 s∈V。
求:从s出发到达其它结点的最短路径。
算法: dijkstra(v,[][]a,[]dist,[]prev)//Dijkstra算法
输入:
有向图G=(V,E,W),V={1,2,…,n}s=1
[][]a= {{},
{0,0,10,MAX,30,100},
{0,MAX,0,50,MAX,MAX},
{0,MAX,MAX,0,MAX,10},
{0,MAX,MAX,20,0,60},
{0,MAX,MAX,MAX,MAX,0}};
输出: prev[]中记录了每一结点的前一结点,依据每个结点对应前一结点值输出遍历全部结点的遍历顺序。
算法步骤:、
·初始S={1}。
·对于i∈V-S,计算1到i的相对S的最短路,长度dist[i]。
·选择V-S中dist值最小的j,将j加入S,修改V-S中顶点的dist 值。
·继续上述过程,直到S=V为止。
具体程序操作过程为: (定义数组dist记录距离,prev记录前一个顶点)
·先计算出结点1到其他结点距离,找到与它最近的点单向连接起来。结点1已被用完记录为true
·从点2记录与它最近的点,连接…
·重复上述步骤。
·(在结果输出方面因为是记录的前一个结点是什么,本来想着是递归解决的,可是总是输出重复的1,没办法,只能多占用一些空间定义一个数组循环调用遍历记录值,然后倒序输出)
package 单源最小路径;
public class 单源最小路径 {
public static void dijkstra(int v,float [][]a,float []dist,int []prev) {
int n=dist.length-1;
if(v<1||v>n)return;
boolean []s =new boolean[n+1];
for(int i=1;i<=n;i++)
{
dist[i]=a[v][i];
s[i]=false;
if(dist[i]==Float.MAX_VALUE)prev[i]=0;
else prev[i]=v;
}
dist[v]=0;s[v]=true;
for(int i=1;i<n;i++)
{
float temp=Float.MAX_VALUE;
int u=v;
for(int j=1;j<=n;j++)
if((!s[j])&&(dist[j]<temp))
{
u=j;
temp=dist[j];
}
s[u]=true;
for(int j=1;j<=n;j++)
if((!s[j])&&(a[u][j])<Float.MAX_VALUE)
{
float newdist=dist[u]+a[u][j];
if(newdist<dist[j])
{
dist[j]=newdist;
prev[j]=u;
}
}
}
}
public static void printit(int []prev,int n) {
int []a =new int [10];
int num=0;
int q=0;
for(int i=n;i>=1&&n!=1;i=prev[n])
{
if(i==1)q=1;
a[num]=n;
num++;
n=prev[n];
if(q==1)break;
}
System.out.print("1");
for(int j=num-1;j>=0;j--)
System.out.print("-->"+a[j]);
}
public static void main(String[] args) {
String []V= {"v1","v2","v3","v4","v5"};
float [][]a= {{},
{ 0,0,10,Float.MAX_VALUE,30,100},
{0,Float.MAX_VALUE,0,50,Float.MAX_VALUE,Float.MAX_VALUE},
{0,Float.MAX_VALUE,Float.MAX_VALUE,0,Float.MAX_VALUE,10},
{0,Float.MAX_VALUE,Float.MAX_VALUE,20,0,60},
{0,Float.MAX_VALUE,Float.MAX_VALUE,Float.MAX_VALUE,Float.MAX_VALUE,0}};
float []dist=new float [6];
int []prev=new int[6];
dijkstra(1,a,dist,prev);
for(int i=1;i<6;i++)
{
printit(prev,i);
System.out.println();
}
}
}