[Java]一個簡單的計算有向賦權圖最短距離的程式碼
阿新 • • 發佈:2018-12-24
在一個有向賦權圖中尋找點a到點b的最短距離,是個簡單問題。
寫了段程式碼,記錄在這裡吧。
以下面的這個圖為例:
計算從點0到點5的最短距離
解決方法:
(1)讀取路線資料,用二維陣列b[i][j],表示點i到點j可以走,距離為其數值。
(2)建立一個堆疊H,壓入起點,堆疊的節點為這個點的編號和它可以到達的點的連結串列。
(3)彈出H最上面的點Last的可到達連結串列T的最後一個可以到達的點M,將這個點號壓入H中。【1】如果H空了,則所有可能找完了。【2】如果T為空,則這個Last點找完了,可以彈出,繼續尋找了。
(4)判斷當前形成的H是不是表示找到了一個新的最短路徑。【1】如果找到了,儲存這個路徑到rList[i],儲存路徑長度到rLen[i],表示起點到點i的最短路徑和最短路徑長度。【2】如果找到的路徑長度大於之前找到的,則這個結果不必要保留,彈出這個點。
(5)重複(3)
執行結果為:
This is a program to calculate the shortest path of a map.
len=6
Path=0 3 6 5
程式碼如下:
【1】Mainclass.java
/** * Created by Firwood on 14-9-23. */ public class Mainclass { public static final int PointNum = 7; public static void main(String[] args){ System.out.println("This is a program to calculate the shortest path of a map."); /* int [][] b = new int[PointNum][PointNum]; for(int i=0;i<PointNum;i++){ for(int j=0;j<PointNum;j++){ b[i][j] = 0; } } b[0][1]=3; b[0][3]=4; b[1][2]=1; b[1][4]=2; b[2][4]=7; b[3][4]=3; b[3][1]=6; */ int[][] b = {{0,2,0,1,0,0,0}, {0,0,0,3,10,0,0}, {4,0,0,0,0,5,0}, {0,0,2,0,2,8,4}, {0,0,0,0,0,0,6}, {0,0,0,0,0,0,0}, {0,0,0,0,0,1,0}}; Map a = new Map(PointNum); a.init(b); PathLen qq = a.getPath(0,5); System.out.println("len=" + qq.len + "\nPath=" + qq.path.toString()); } }
【2】Map.java
//-------java //This is a class to calculate a map //Go througth the map and find the shortest way from a to b //return the path and give the shortest length // //Write by Firwood //2014-09-22 public class Map{ public final static int MAX = 9999999; //saving the numbet of all Point int iPointNum; //saving the length from start point to [i] int[] rLen; //saving the path from start point to [i] List[] rList; //saving the source length of matrix int[][] roads; //saving the road of each Point can go to List[] RoadListArray; //the calculate heap,it's Node is a point number and its //connected point PointHeap calcHeap; ////////////////////////////////////////////////////////////////////// public Map(int num){ // iPointNum = num; roads= new int[iPointNum][iPointNum]; rLen = new int[iPointNum]; for(int i = 0; i < iPointNum; i++){ rLen[i] = MAX; } rList = new List[iPointNum]; RoadListArray = new List[iPointNum]; for(int i=0;i<iPointNum;i++){ rList[i] = new List(); RoadListArray[i] = new List(); } calcHeap = new PointHeap(); } public void init(int[][] matrix){ // //transfer matrix to roads, roads is //using to save the length of node[i] //to node[j] for(int i = 0; i < iPointNum; i++){ for(int j = 0; j < iPointNum; j++){ if(matrix[i][j] != 0){ roads[i][j] = matrix[i][j]; }else{ if(i != j ){ roads[i][j] = MAX; //this means it is a length which is can't //reach }else{ roads[i][j] = 0; } } } } // for(int i = 0; i< iPointNum; i++){ for(int j= 0; j < iPointNum; j++){ if(matrix[i][j] != 0){ RoadListArray[i].push(j); } } } } public void CalcPath(int endPoint){ //the result is saving in the rLen(for length) and rList(for the Path) while(!calcHeap.isEmpty()){ //empty means the heap is out //every path from the start point is tried //finding path is over!!! HeapNode tempHeapNode = calcHeap.last; if(tempHeapNode.toPoint.isEmpty()){ //empty means the last node can't go any other point //should pop this point out, try other point calcHeap.pop(); continue; } int tempPoint = tempHeapNode.toPoint.pop(); HeapNode temp = new HeapNode(); temp.set(tempPoint, RoadListArray[tempPoint]); calcHeap.push(temp); if(!ShorterPath()){ //means this path is longer than other found path before //there is no need to using this point to brith next point //you should use the shorter path //pop this point out, to find next calcHeap.pop(); continue; } } } public PathLen getPath(int start, int end){ //begin method for calc the path from start point to the end point // PathLen thePath = new PathLen(); if(start == end){ //if the start point is the end point //the answer length is 0, and path is not go thePath.len = 0; thePath.path.push(start); return thePath; } HeapNode startPoint = new HeapNode(); startPoint.set(start, RoadListArray[start]); calcHeap.push(startPoint); ShorterPath(); //the real calc all path from the start point CalcPath(end); //get the needed path result thePath.set(rLen[end], rList[end]); return thePath; } public boolean ShorterPath(){ //using the "calcHeap" to calc is a new shorter path is found //if found a new path , using the rList[] to save the path //using the rLen[] to saving the length //and return true; //if the found path is longer than before return false HeapNode index = calcHeap.begin.next; int a = index.pNum; int b = 0; int sum = 0; index = index.next; while(index != calcHeap.end){ b = index.pNum; sum += roads[a][b]; a = b; index = index.next; } if(sum < rLen[b]){ rLen[b] = sum; rList[b] = calcHeap.getList(); return true; } return false; } } /////////////////////////////////////////////////////////////////////////////////// class PathLen{ List path; int len; public PathLen(){ path = new List(); len = 0; } public void set(int num, List setList){ len = num; path = setList.clone(); } }
【3】List.java
//----List.java
//Write by Firwood
//2014-09-22
public class List{
//
ListNode begin;
ListNode end;
public List(){
begin = new ListNode();
end = new ListNode();
begin.next = end;
end.prev = begin;
}
public void push(int num){
ListNode last = end.prev;
ListNode temp = new ListNode(num);
temp.prev = last;
temp.next = end;
last.next = temp;
end.prev = temp;
}
public int pop(){
if(isEmpty()) return 0;
ListNode temp = end.prev;
int t = temp.key;
temp.prev.next = end;
end.prev = temp.prev;
return t;
}
public boolean isEmpty(){
return (end.prev == begin);
}
public List clone(){
//
List temp = new List();
ListNode p = begin.next;
while(p != end){
temp.push(p.key);
p = p.next;
}
return temp;
}
public String toString(){
String str="";
ListNode index = begin.next;
while(index != end){
str += index.key+" ";
index = index.next;
}
return str;
}
}
class ListNode{
//
int key;
ListNode prev;
ListNode next;
public void init(){
key = 0;
prev = null;
next = null;
}
public ListNode(){
init();
}
public ListNode(int a){
init();
key = a;
}
}
【4】PointHeap.java
///////-----PointHeap.java
//
//Write by Firwood
//2014-09-22
public class PointHeap{
//
HeapNode begin;
HeapNode end;
//the last Node of this list,
//if the list is empty last is the begin
HeapNode last;
public PointHeap(){
begin = new HeapNode();
last = begin;
end = new HeapNode();
begin.next = end;
end.prev = begin;
}
public void push(HeapNode tNode){
//
last.next = tNode;
tNode.prev = last;
tNode.next = end;
end.prev = tNode;
last = tNode;
}
public HeapNode pop(){
if(isEmpty()) return begin;
HeapNode tNode = last;
last.prev.next = end;
end.prev = last.prev;
last = end.prev;
return tNode;
}
public boolean isEmpty(){
return (end.prev == begin);
}
public List getList(){
//return a path list from begin point to end point
List tempList = new List();
HeapNode a = begin.next;
while(a != end){
tempList.push(a.pNum);
a = a.next;
}
return tempList;
}
}
////////////////////////
class HeapNode{
//
int pNum;
List toPoint;
HeapNode prev;
HeapNode next;
public void init(){
pNum = 0;
toPoint = new List();
prev = null;
next = null;
}
public HeapNode(){
init();
}
public void set(int num, List ilist){
pNum = num;
toPoint = ilist.clone();
}
}