Dijkstra

Dijkstra图的最短路径算法。

搜索过程中有 一个搜索过的节点 used ,一个 起始点到各点的最短距离distance, 一个前驱节点表 prev 用来标识这个节点在distance存储的距离的前驱节点,最后用于生成最短路径。

1:将 start 放入 used ,从起始点 start 遍历周边节点,将可到达的节点的距离放入 distance ,并将 prev 中的对应节点的前驱设置为 start。

private static void init(boolean[] used, int[] distance, int[] previous, int[][] graph){
		for (int i = 0; i < used.length; i++){
			used[i] = false;
			distance[i] = graph[GraphUtils.FROM][i];
			if (graph[GraphUtils.FROM][i] != GraphUtils.MAX){
				previous[i] = GraphUtils.FROM;
			} else {
				previous[i] = -1;
			}
		}
		previous[GraphUtils.FROM] = -1;
		used[GraphUtils.FROM] = true;
		distance[GraphUtils.FROM] = 0;
	}


2:在distance 中选择没有 used 的最短的节点 min。

3:将 min 放入 used 。遍历 used 周边节点 around 的距离 dis ,如果 around 没在used中 并且 distance[min] +  dis < distance[around],那么distance[around] = distance[min] +  dis,pre[around] = min。

4:循环 2,3  直到没有min

public static void dijkstra(int[][] graph, int to){
		int nodeNum = graph.length;
		boolean[] used = new boolean[nodeNum];
		int[] distance = new int[nodeNum];
		int[] previous = new int[nodeNum];
		init(used, distance, previous, graph);
		LOG.d(distance);
		for (int i = 0; i < nodeNum; i++){
			int minIndex = GraphUtils.FROM;
			int min = GraphUtils.MAX;
			for (int j = 0; j < nodeNum; j++){
				if ((!used[j]) && distance[j] < min){
					minIndex = j;
					min = distance[j];
				}
			}
			if (min < GraphUtils.MAX){
				used[minIndex] = true;
				for (int j = 0; j < nodeNum; j++){
					if ((!used[j]) && graph[minIndex][j] != GraphUtils.MAX){
						if (distance[minIndex] + graph[minIndex][j] < distance[j]){
							distance[j] = distance[minIndex] + graph[minIndex][j];
							previous[j] = minIndex;
						}
					}
				}
			}
		}
		LOG.d(used);
		LOG.d(previous);
		LOG.d(distance);
		LOG.d(printLine(getLine(previous, to)));
	}


5:在prev中找到目标节点 end,prev[end] <- prev[prev[end]] <- ...... prev[start] 为最短路径。

	public static int[] getLine(int[] prev, int to){
		int[] roleLine = new int[prev.length];
		int i = to;
		int j = 0;
		roleLine[j++] = to;
		while (i >= 0){
			roleLine[j++] = prev[i];
			i = prev[i];
		}
		return Arrays.copyOf(roleLine, j);
	}
	
	public static String printLine(int[] line){
		StringBuffer sb = new StringBuffer();
		for (int i = line.length - 2; i >= 0; i--){
			sb.append(line[i]);
			if (i - 1 >= 0)
				sb.append(" -> ");
		}
		return sb.toString();
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值