思路:
- 令S={源点S+已经确定的最短路径的顶点Vi};
- 对任一未收录的顶点V,定义dist[V]为S到V的最短路径长度,但该路径仅经过S中的顶点,即路径{S->(Vi属于S)->V}d的最小长度。
- 路径是按照递增(非递减)的顺序生成的,且:
a. 真正的最短路径必须只经过S中的顶点;
b. 每次从未收录的顶点中选dist最小的收录(贪心算法);
c. 增加一个V到S可能影响一个人W的dist的值,所以:
dist[W] = min{dist[W],dist[V] + <V,W>的权重};
- dist[W] = S到W的最短距离;
dist[S] = 0;
path [W] = S到W的路上经过的某顶点;
代码:
public class Dijkstra {
private Queue<Integer> visited;
int[] dist;
public Dijkstra(int len) {
visited = new LinkedList<Integer>();
dist = new int[len];
}
private int getIndex(Queue<Integer> q, int[] dist) {
int k = -1;
int min_num = Integer.MAX_VALUE;
for (int i = 0; i < dist.length; i++) {
if (!q.contains(i)) {
if (dist[i] < min_num) {
min_num = dist[i];
k = i;
}
}
}
return k;
}
@SuppressWarnings("unchecked")
public void dijkstra(int[][] weight, Object[] str, int v) {
@SuppressWarnings("rawtypes")
HashMap path;
path = new HashMap<Integer, String>();
for (int i = 0; i < str.length; i++) {
path.put(i, "");
}
for (int i = 0; i < str.length; i++) {
path.put(i, path.get(i) + "" + str[v]);
if (i == v)
dist[i] = 0;
else if (weight[v][i] != -1) {
dist[i] = weight[v][i];
path.put(i, path.get(i) + "-->" + str[i]);
} else
dist[i] = Integer.MAX_VALUE;
}
visited.add(v);
while (visited.size() < str.length) {
int k = getIndex(visited, dist);// 获取未访问点中距离源点最近的点
visited.add(k);
if (k != -1) {
for (int j = 0; j < str.length; j++) {
if (weight[k][j] != -1)// 判断k点能够直接到达的点
{
if (dist[j] > dist[k] + weight[k][j]) {
dist[j] = dist[k] + weight[k][j];
path.put(j, path.get(k) + "-->" + str[j]);
}
}
}
}
}
for (int h = 0; h < str.length; h++) {
System.out.printf(str[v] + "-->" + str[h] + ":" + dist[h] + " ");
if (dist[h] == Integer.MAX_VALUE) {
System.out.print(str[v] + "-->" + str[h] + "之间没有可通行路径");
}
else {
System.out.print(str[v] + "-" + str[h] + "之间有最短路径,具体路径为:" + path.get(h).toString());
}
System.out.println();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[][] weight = { { 0, -1, 10, -1, 30, 100 },
{ -1, 0, 5, -1, -1, -1 },
{ -1, -1, 0, 50, -1, -1 },
{ -1, -1, -1, 0, -1, 10 },
{ -1, -1, -1, 20, 0, 60 },
{ -1, -1, -1, -1, -1, 0 } };
String[] str = { "V1", "V2", "V3", "V4", "V5", "V6" };
int len = str.length;
Dijkstra dijkstra = new Dijkstra(len);
for (int i = 0; i < str.length; i++) {
dijkstra.dijkstra(weight, str, i);
}
}