最短路径问题

最短路算法的求解,都是基于下列事实:节点A到节点B的最短路径有两种可能,一种是直接从A到B,另一种是从A经过若干个节点到B。

 

Dijkstra算法:单源最短路径问题,时间复杂度为O(n^2);不能处理权值为负的边

Floyd算法:求解图中任意节点之间的最短路径,时间复杂度为O(n^3);可以处理任意数值权重的边。

 

程序(朴素版本)

Dijkstra算法

public class Dijkstra {
	public int[] getShortestPath(int[][] adjacencyMatrix) {
		if (adjacencyMatrix == null || adjacencyMatrix.length == 0
				|| adjacencyMatrix[0].length == 0) {
			return null;
		}

		int n = adjacencyMatrix.length;
		boolean[] visited = new boolean[n];
		int[] shortestPath = new int[n];
		visited[0] = true;
		int lastNodes = n - 1;

		// initialize
		for (int i = 0; i < n; i++) {
			shortestPath[i] = adjacencyMatrix[0][i];
		}

		while (lastNodes > 0) {
			int shortest = Integer.MAX_VALUE;
			int idx = 0;
			for (int i = 1; i < n; i++) {
				if (visited[i]) {
					continue;
				}
				if (shortestPath[i] < shortest) {
					// choose the nearby node
					shortest = shortestPath[i];
					idx = i;
				}
			}
			visited[idx] = true;
			// update shortest path
			for (int i = 1; i < n; i++) {
				if (visited[i] || adjacencyMatrix[idx][i] == Integer.MAX_VALUE) {
					continue;
				}
				shortestPath[i] = Math.min(shortestPath[i], shortestPath[idx]
						+ adjacencyMatrix[idx][i]);
			}
			--lastNodes;
		}

		return shortestPath;
	}
}

 

Floyd算法

经典的三层for循环结构,

public class Floyd {
	public int[][] getShortestMatrix(int[][] adj) {
		if (adj == null || adj.length == 0 || adj[0].length == 0) {
			return null;
		}

		int n = adj.length;

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				for (int k = 0; k < n; k++) {
					if (adj[i][k] == Integer.MAX_VALUE
							|| adj[j][k] == Integer.MAX_VALUE) {
						continue;
					}
					if (adj[i][k] + adj[j][k] < adj[i][j]) {
						adj[i][j] = adj[i][k] + adj[j][k];
					}
				}
			}
		}

		return adj;
	}
}

 

posted @ 2015-07-27 21:20  Chapter  阅读(180)  评论(0编辑  收藏  举报