单源最短路径Dijkstra算法的简单实现

思路:

  1. 令S={源点S+已经确定的最短路径的顶点Vi};
  2. 对任一未收录的顶点V,定义dist[V]为S到V的最短路径长度,但该路径仅经过S中的顶点,即路径{S->(Vi属于S)->V}d的最小长度。
  3. 路径是按照递增(非递减)的顺序生成的,且:
    a. 真正的最短路径必须只经过S中的顶点;
    b. 每次从未收录的顶点中选dist最小的收录(贪心算法);
    c. 增加一个V到S可能影响一个人W的dist的值,所以:
   	 dist[W] = min{dist[W],dist[V] + <V,W>的权重};
  1. 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);
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值