dijkstra算法
思路
- dijkstra算法是一种解决单源最短路径的算法,能够找到起点(也叫做源点)到其他各个顶点的最短路径
- 将每条边的路径大小用邻接矩阵weight[i][j]存储将源点到其他各个点的距离用dis[n]数组存储,使用visit[n]数组来标记某个点是否已经被访问,并将其初始化
- 在未被访问的点中找到dis中距离源点最近的点dis[index],并将其设置未已经被访问
- 如果未被访问的顶点的 dis[i] > dis[index] + weight[index][i],则 dis[i] = dis[index] + weight[index][i],该操作叫做松弛
- 重复3、4步骤,即可找到源点到各个顶点的最小值
代码
public class Dijkstra {
int[] dis;
private final static int INF = Integer.MAX_VALUE;
public int[] dijkstra(int n, int[][] weight) {
dis = new int[n];
boolean[] visit = new boolean[n];
for(int i=0; i<n; i++) {
dis[i] = weight[0][i];
visit[i] = false;
}
visit[0] = true;
dis[0] = 0;
int j = 0;
while(j<n-1) {
int min = INF;
int index = 0;
for(int i=0; i<n; i++) {
if(!visit[i] && min > dis[i] ) {
min = dis[i];
index = i;
}
}
visit[index] = true;
for(int i=0; i<n; i++) {
if(!visit[i] && weight[index][i]!=INF && dis[i] > dis[index] + weight[index][i]) {
dis[i] = dis[index] + weight[index][i];
}
}
System.out.println(index + " 离源点的距离为: " + dis[index]);
j++;
}
return dis;
}
public static void main(String[] args) {
int n = 7;
int[][] weight = new int[7][7];
weight[0]=new int[]{INF,5,7,INF,INF,INF,2};
weight[1]=new int[]{5,INF,INF,9,INF,INF,3};
weight[2]=new int[]{7,INF,INF,INF,8,INF,INF};
weight[3]=new int[]{INF,9,INF,INF,INF,4,INF};
weight[4]=new int[]{INF,INF,8,INF,INF,5,4};
weight[5]=new int[]{INF,INF,INF,4,5,INF,6};
weight[6]=new int[]{2,3,INF,INF,4,6,INF};
int[] dis = new Dijkstra().dijkstra(n, weight);
System.out.println(Arrays.toString(dis));
}
}
floyd算法
思路
- 将路径长度存储在邻接矩阵 weight[i][j] 中
- 设置中间点k,判断 i 到 j 的距离 weight[i][j] 是否大于 i 先到 k,再从 k 到 j 的距离之和(weight[i][j] > weight[i][k] + weight[k][j]),如果成立,则修改 weight[i][j] = weight[i][k] + weight[k][j] 的路径长度
- 每个顶点都可作为中间点,最终即可得到 i 到 j 的最短路径(i,j为任意点)
代码
public void floyd(int n, int[][] weight) {
for(int k=0; k<n; k++)
for(int i=0; i<n ;i++)
for(int j=0; j<n; j++)
if(weight[i][j] < weight[i][k] + weight[k][j])
weight[i][j] = weight[i][k] + weight[k][j];
}
SPAF解决负边权(待更)