/**
* 按路径长度递增次序产生最短路径算法: 把V分成两组:
* (1)S:已求出最短路径的顶点的集合
* (2)V-S=T:尚未确定最短路径的顶点集合
* 将T中顶点按最短路径递增的次序加入到S中,
* 保证:
* (1)从源点V0到S中各顶点的最短路径长度都不大于 从V0到T中任何顶点的最短路径长度
* (2)每个顶点对应一个距离值 S中顶点:从V0到此顶点的最短路径长度 T中顶点: 从V0到此顶点的只包括S中顶点作中间 顶点的最短路径长度
*
* 依据:可以证明V0到T中顶点Vk的最短路径, 或是从V0到Vk的 直接路径的权值; 或是从V0经S中顶点到Vk的路径权值之和
*
*
* 算法步骤如下:
* 1. 初使时令 S={V0},T={其余顶点},T中顶点对应的距离值 若存在<V0,Vi>,d(V0,Vi)为<V0,Vi>弧上的权值
* 若不存在<V0,Vi>,d(V0,Vi)为∝
* 2. 从T中选取一个其距离值为最小的顶点W且不在S中,加入S
* 3. 对其余T中顶点的距离值进行修改:若加进W作中间顶点,从V0到Vi的 距离值缩短,则修改此距离值 重复上述步骤2、3,
* 直到S中包含所有顶点,即W=Vi为止
*
*
*
*/
public class Dijkstra {
/**
* 起始点到其他所有点的最短路径。
*
* @param adj
* 邻接矩阵
* @param n
* 一共多少个顶点,编号从0到n-1
* @param v
* 起始点的编号
*/
public void dijkstra(int[][] adj, int n, int v) {
int[] dist = new int[n];
boolean[] isPassed = new boolean[n];
isPassed[v] = true;
int passedCount = 1;
for (int i = 0; i < n; i++) {
dist[i] = adj[v][i];
}
int c = v;
while (passedCount < n) {
c = getMinV(adj, isPassed, n, c);
isPassed[c] = true;
for (int i = 0; i < n; i++) {
if (!isPassed[i] && adj[c][i] != Graph.INFINITY) {
if (adj[c][i] + dist[c] < dist[i]) {
dist[i] = adj[c][i] + dist[c];
}
}
}
passedCount++;
}
Tools.printArray(dist);
}
private int getMinV(int[][] adj, boolean[] isPassed, int n, int c) {
int minVertex = 0;
int min = Graph.INFINITY;
for (int i = 0; i < n; i++) {
if (!isPassed[i] && adj[c][i] != Graph.INFINITY) {
if (adj[c][i] < min) {
min = adj[c][i];
minVertex = i;
}
}
}
return minVertex;
}
public static void main(String[] args) {
int n = 6;
Graph g = Graph.createDirectedGraph(n, "dij_1.txt");
g.printGraph();
g.fillGraphWithInfinity();
System.out.println("Dijkstra: ");
Dijkstra dij = new Dijkstra();
dij.dijkstra(g.adjMatrix, n, 0);
}
}
Dijkstra
最新推荐文章于 2025-05-27 15:15:53 发布