package 最短路径;
/**
* 邻接矩阵
* @author 小宇
*/
public class MGraph {
//顶点为空
public static final int NULL = 1000;
//邻接矩阵
int[][] edges = new int[9][9];
//顶点数和边数
int n,e;
}
/**
* 此代码用于生成邻接矩阵
* 并显示
* @author 小宇
*/
public class CreateMgraph {
//根据二维数组,生成邻接矩阵
public void createMat(MGraph g, int A[][], int n)
{
int i, j;
g.n = n;
g.e = 0;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
{
g.edges[i][j] = A[i][j];
if(g.edges[i][j] != MGraph.NULL)
g.e++;
}
}
//输出邻接矩阵
public void DispMat(MGraph g)
{
int i, j;
for(i = 0; i < g.n; i++)
{
for(j = 0; j < g.n; j++)
{
if(g.edges[i][j] == MGraph.NULL)
System.out.print("-" + " ");
else
System.out.print(g.edges[i][j] + " ");
}
System.out.println();
}
}
}
/**
* 核心代码:生成最短路径
* @author 小宇
*/
public class GetShortestPath {
//Dijkstra算法
public static void Dijkstra(MGraph mgraph,int v0)
{
final int INFINITY = 65535;
//用于存储最短路径下标数组
int[] pathMatirx = new int[9];
//用于存储到各点最短路径权值
int[] shortPathTable = new int[9];
int min,v,w,k = 0;
//finalGot[n] = 1表示求得v0 - vn最短路径
int[] finalGot = new int[9];
//初始化数据
for(v = 0; v < mgraph.n; v++)
{
//全部顶点初始化为未知最短路径状态
finalGot[v] = 0;
//将与与v0有连线的点加上权值
shortPathTable[v] = mgraph.edges[v0][v];
//初始化路径数组为0
pathMatirx[v] = 0;
}
//v0至v0路径为0
shortPathTable[v0] = 0;
//v0至v0不须求路径
finalGot[v0] = 1;
for(v= 1; v < mgraph.n; v++)
{
min = INFINITY;
//寻找距v0最近顶点
for(w = 0; w < mgraph.n; w++)
{
if(finalGot[w] == 0 && shortPathTable[w] < min)
{
k = w;
min = shortPathTable[w];
}
}
//将找到的顶点标记为1
finalGot[k] = 1;
//修正当前最短路径及距离
for(w = 0; w < mgraph.n; w++)
{
//如果经过v顶点的路径比现在这条路径距离短的话
if(finalGot[w] == 0 && (min + mgraph.edges[k][w] < shortPathTable[w]))
{
shortPathTable[w] = min + mgraph.edges[k][w];
pathMatirx[w] = k;
}
}
}
//输出
System.out.println("Dijkstra算法求得最短路径: ");
for(v = 1; v < mgraph.n; v++)
{
k = v;
System.out.print(k + "->");
while(k != v0)
{
k = pathMatirx[k];
System.out.print(k + "->");
}
System.out.println();
}
}
//-----------------------------------------------------
//弗洛伊德算法算法基本思想与Dijkstra算法相似
public static void Floyd(MGraph mgraph)
{
int[][] shortPathTable = new int[9][9];
int[][] pathMatirx = new int[9][9];
int v, w, k;
for(v = 0; v < mgraph.n; v++)
{
for(w = 0; w < mgraph.n; w++)
{
shortPathTable[v][w] = mgraph.edges[v][w];
pathMatirx[v][w] = w;
}
}
for(k = 0; k < mgraph.n; k++)
{//1
for(v = 0; v < mgraph.n; v++)
{//2
for(w = 0; w < mgraph.n; w++)
{//3
if(shortPathTable[v][w] > shortPathTable[v][k] + shortPathTable[k][w])
{
shortPathTable[v][w] = shortPathTable[v][k] + shortPathTable[k][w];
pathMatirx[v][w] = pathMatirx[v][k];
}
}//3
}//2
}//1
//显示
System.out.println("Floyd算法求得最短路径:");
for(v = 0; v < mgraph.n; v++)
{
for(w = v + 1; w < mgraph.n; w++)
{
System.out.print("v" + v + "->v" + w + "weight:" + shortPathTable[v][w] + " ");
k = pathMatirx[v][w];
System.out.print("path:" + v);
while(k != w )
{
System.out.print("->" + k);
k = pathMatirx[k][w];
}
System.out.println("->" + w);
}
System.out.println();
}
}
}
/**
* 测试代码
* @author 小宇
*
*/
public class Test
{
public static void main(String[] args)
{
MGraph mg = new MGraph();
int[][] array = new int[9][9];
for(int i = 0;i < 9; i++)
for(int j = 0;j < 9; j++)
array[i][j] = MGraph.NULL;
array[0][1] = 1;
array[1][0] = 1;
array[0][2] = 5;
array[2][0] = 5;
array[1][2] = 3;
array[2][1] = 3;
array[1][3] = 7;
array[3][1] = 7;
array[3][4] = 2;
array[4][3] = 2;
array[1][4] = 5;
array[4][1] = 5;
array[2][4] = 1;
array[4][2] = 1;
array[2][5] = 7;
array[5][2] = 7;
array[4][5] = 3;
array[5][4] = 3;
array[3][6] = 3;
array[6][3] = 3;
array[4][6] = 6;
array[6][4] = 6;
array[4][7] = 9;
array[7][4] = 9;
array[5][7] = 5;
array[7][5] = 5;
array[6][7] = 2;
array[7][6] = 2;
array[6][8] = 7;
array[8][6] = 7;
array[7][8] = 4;
array[8][7] = 4;
CreateMgraph cm = new CreateMgraph();
cm.createMat(mg, array, 9);
cm.DispMat(mg);
GetShortestPath.Dijkstra(mg, 0);
GetShortestPath.Floyd(mg);
}
}