public class Dijkstra {
/**
* 典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径
* 该算法要求图中不存在负权边
* 把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示)
* 第二组为其余未确定最短路径的顶点集合(用U表示)
*/
public static int MAXNUM = 6;
static int M = Integer.MAX_VALUE;
public static int[] dist = new int[MAXNUM + 1]; // 计算v0点到任何一点的距离
public static int[] prev = new int[MAXNUM + 1]; // 保存到i这一点最近的上一个节点
public static void main(String[] args) {
int[][] A = {
{0, 7, 9, M, M, 14},
{7, 0, 10, 15, M, M},
{9, 10, 0, 11, M, 2},
{M, 15, 11, 0, 6, M},
{M, M, M, 6, 0, 9},
{14, M, 2, M, 9, 0}
};
dijkstra(1, A);
for (int a : dist) {
System.out.println(a);
}
}
public static void dijkstra(int v0, int[][] A) {
boolean S[] = new boolean[MAXNUM + 1]; // 判断是否已存入该点到S集合中,初始为false
S[v0] = true;
int n = MAXNUM;
// 计算v0到其他点的距离,dist1-6:0,7,9,M,M,14.第一次找的的点prev一定是v0
for (int i = 1; i <= n; i++) { // 1-n
dist[i] = A[v0 - 1][i - 1];
if (dist[i] == Integer.MAX_VALUE) {
prev[i] = -1;
} else {
prev[i] = v0;
}
}
// 计算v0的邻接点中距离最短的一个点u
for (int i = 2; i <= n; i++) {
int mindist = Integer.MAX_VALUE;
int u = v0; // 找出当前未使用的点j的dist[j]最小值
for(int j = 1; j <= n; ++j) {
if(!S[j] && dist[j] < mindist) {
u = j; // u保存当前邻接点中距离最小的点的号码
mindist = dist[j];
}
}
S[u] = true;
// 为每一点j找到最短的路径(初始化均为v0至j),若从u到j比从v0直接到j小,则更新
for (int j = 1; j <= n; j++) {
if (!S[j] && A[u - 1][j - 1] < Integer.MAX_VALUE) {
if (dist[u] + A[u - 1][j - 1] < dist[j]) {
dist[j] = dist[u] + A[u - 1][j - 1];
prev[j] = u; // 记录前驱顶点
}
}
}
}
}
}
2.项目中的Dijkstra算法
public class Dijkstra {
private static final Logger LOG = LoggerFactory.getLogger(Dijkstra.class);
public static void computePaths(Vertex source,Set<Vertex> all_node,long bW) {
LOG.info("===aoniBod Start computePaths():source={},Set<Vertex>={}",source.name,all_node);
source.minDistance = 0;
PriorityQueue<Vertex> vertexQueue = new PriorityQueue<Vertex>();
vertexQueue.add(source);
all_node.remove(source);
while (!all_node.isEmpty()) {
LOG.info("===aoniBod number of left node ={}",all_node.size());
Vertex u = vertexQueue.poll();
LOG.info("===aoniBod Dijkstra Current u={}",u.name);
//update the shortest distance of all nodes that are adjacent to node u
for (Edge e : u.adjacencies) {
LOG.info("****adjacent node name={}",e.target.name);
for(Vertex node : all_node){
if(node.name.equals(e.target.name)){
LOG.info("*****Find target.name=node.name={}",node.name);
double weight = e.weight;
double distanceThroughU = u.minDistance + weight;
if (distanceThroughU < node.minDistance) {
node.minDistance = distanceThroughU ;
node.previous = u;
}
}
}
}
LOG.info("====Finish Updating the shortest distance====");
//find the nearest node from source node
Vertex tmp_node = null;
double tmp_dist = Double.MAX_VALUE;
for(Vertex node:all_node){
if(node.minDistance < tmp_dist) {
tmp_dist = node.minDistance;
tmp_node = node;
}
}
LOG.info("===the shortest node from source is {}", tmp_node.name);
//LOG.info("=====The node nearest from source is:{}",tmp_node);
vertexQueue.add(tmp_node);
all_node.remove(tmp_node);
}
LOG.info("===aoniBod Finish computePaths()====");
}
public static List<Vertex> getShortestPathTo(Vertex target) {
LOG.info("===aoniBod Start getShortestPathTo Vertex={}",target.name);
List<Vertex> path = new ArrayList<Vertex>();
List<Long> nameList = new ArrayList<Long>();
for (Vertex vertex = target; vertex != null; vertex = vertex.previous){
path.add(vertex);
nameList.add(vertex.name);
}
Collections.reverse(path);
Collections.reverse(nameList);
LOG.info("===aoniBod Path Result={}",nameList);
return path;
}
}
/*
* Floyd,图的最短路径(动态规划)
*/
public class Floyd {
public static int M = Integer.MAX_VALUE;
/**
*
*/
public static void main(String[] args) {
int[][] dist = {
{0, 1, 4, M, M, M},
{1, 0, 2, 7, 5, M},
{4, 2, 0, M, 1, M},
{M, 7, M, 0, 3, 2},
{M, 5, 1, 3, 0, 6},
{M, M, M, 2, 6, 0}
};
int[][] res = floyd(dist, 6);
for (int[] a : res) {
for (int b: a) {
System.out.print(b);
}
System.out.println();
}
}
public void printG(int[][] G,int n){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
System.out.println(i+"->"+j+" "+G[i][j]);
}
}
}
public static int[][] floyd(int[][] G,int n){
int[][] Dis = new int[n][n];
for(int q = 0; q < n; q++) {
for(int w = 0; w < n; w++) {
Dis[q][w] = G[q][w];
}
}
for(int k = 0; k < n; k++) { // k步从i到j
for(int i = 0; i < n; i++ ) {
for(int j = 0; j < n; j++) {
if(Dis[i][k] != M && Dis[k][j] != M && Dis[i][j] > Dis[i][k] + Dis[k][j]) { // 考虑M + 任何为负
Dis[i][j]=Dis[i][k]+Dis[k][j];
}
}
}
}
return Dis;
}
}
参考链接及相应算法讲解:
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html
http://blog.csdn.net/limao314/article/details/14451193