最短路径问题

最短路算法的求解,都是基于下列事实:节点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;

	}

}

 

你可能感兴趣的:(最短路径)