求解羅馬尼亞度假問題,找到從Arad到Bucharest的一條路徑,java實現。
阿新 • • 發佈:2018-12-13
運用迪傑斯特拉演算法(Dijkstra演算法),找到Arad到Bucharest的最短路徑。註釋掉的內容不用管。
import java.util.Scanner; public class path { static Scanner s=new Scanner(System.in); public static void main(String[] args) { String[] names={"Drobeta","Mehadia","Lugoj","Timisoara","Arad","Zerind","Oradea","Craiova","Rimnicu Vilcea","Sibiu","Pitesti", "Bucharest","Fagaras"}; arc[] arc={new arc("Arad","Zerind",75),new arc("Arad","Sibiu",140),new arc("Arad","Timisoara",118),new arc("Timisoara","Lugoj",111), new arc("Lugoj","Mehadia",70),new arc("Mehadia","Drobeta",75),new arc("Drobeta","Craiova",120),new arc("Craiova","Pitesti",138),new arc("Craiova","Rimnicu Vilcea",146), new arc("Pitesti","Bucharest",101),new arc("Bucharest","Fagaras",211), new arc("Rimnicu Vilcea","Pitesti",97),new arc("Rimnicu Vilcea","Sibiu",80),new arc("Sibiu","Fagaras",99),new arc("Sibiu","Oradea",151),new arc("Oradea","Zerind",71)}; Graph gra = createGraph(names,arc); System.out.println(gra); int path[]=Dijkstra(gra,"Arad"); Dispath(gra,path,"Arad","Bucharest"); } static Graph createGraph(String[] names,arc[] arc){//String儲存節點名稱,arc儲存每一個節點的邊所到到的邊和權值 int n=names.length; Graph graph =new Graph(n); for(int i=0;i<n;i++ ){ graph.graph[i]=new vexnode(); graph.graph[i].name=names[i]; } for(int i=0;i<arc.length;i++){ add(arc[i].name1,arc[i].name2,arc[i].weight,graph); add(arc[i].name2,arc[i].name1,arc[i].weight,graph); } return graph; } static void add(String name1,String name2,int weight,Graph graph){ int i=find(name1,graph); int j=find(name2,graph); if(i==-1||j==-1) { System.out.println(name1+"->"+name2+"失敗"); return; } arcnode ar=new arcnode(); ar.ver=j; ar.weight=weight; ar.nextarc=null; arcnode pre = null; arcnode temp=graph.graph[i].firstarc; if(temp==null){//頂點之前無邊 graph.graph[i].firstarc=ar; } else {while(temp!=null)//頂點之前無邊 { pre=temp; temp=temp.nextarc; } pre.nextarc=ar; } } static int find(String name,Graph graph){ int n=graph.graph.length; for(int i=0;i<n;i++ ) if(graph.graph[i].name.equals(name)) return i; return -1; } static int[] Dijkstra(Graph graph,String start){ int v=find(start,graph); int[] path=new int[graph.graph.length]; for(int i=0;i<graph.graph.length;i++) path[i]=-1; int[] dist=new int[graph.graph.length]; for(int i=0;i<graph.graph.length;i++) dist[i]=1000000; int[] s=new int[graph.graph.length];//s儲存那哪些結點已經被訪問過 if(v==-1){ System.out.println("無"+start+"這個節點"); return null; } arcnode p =graph.graph[v].firstarc; while(p!=null) { path[p.ver]=v; dist[p.ver]=p.weight; p=p.nextarc; } s[v]=1;//頂點V加入s中 int u=0,mindis=1000000; for(int i=0;i<graph.graph.length;i++){ mindis=1000000; for(int j=0;j<graph.graph.length;j++) if((s[j]==0)&&dist[j]<mindis){ u=j; mindis=dist[j]; } s[u]=1;//頂點u加入s中 p =graph.graph[u].firstarc; while(p!=null) { if(s[p.ver]==0) if(dist[p.ver]>dist[u]+p.weight){ dist[p.ver]=dist[u]+p.weight; path[p.ver]=u; } p=p.nextarc; } } return path; } static void Dispath(Graph graph,int[] path,String start,String end){ int sta=find(start,graph); int en=find(end,graph); if(sta==-1||en==-1){ System.out.println("沒有找到相關結點"); return; } if(path[en]==-1){ System.out.println("路徑有誤"); return; } else{ int temp=0,i=1; int[] path1=new int[path.length]; path1[0]=en; temp=path1[0]; while(path[temp]!=sta){ path1[i]=path[temp]; temp=path1[i]; i++; } path1[i]=sta; System.out.println(start+"到"+end+"最短路徑為:"); for(int j=i;j>0;j--){ System.out.print(graph.graph[path1[j]].name+"-->"); } System.out.println(graph.graph[path1[0]].name); } } /*static Graph createGraph(){//互動介面 //互動介面 int n; System.out.println("請輸入總節點數:"); n=s.nextInt(); Graph graph =new Graph(n); System.out.println("請輸入所有的節點名稱,中間用空格隔開"); for(int i=0;i<n;i++ ){ String name=s.next(); graph.graph[i]=new vexnode(); graph.graph[i].name=name; } for(int i=0;i<n;i++ ){ while (true){ System.out.println("請輸入節點"+graph.graph[i].name+"的邊,先輸入這條邊所到的節點名稱,空格,輸入權值,輸入0結束當前節點邊的建立"); String name=s.next(); if(name.equals("0")) break; int weight=s.nextInt(); for(int j=0;j<n;j++){ if(graph.graph[j].name.equals(name)) { arcnode arc=new arcnode(); arc.ver=j; arc.weight=weight; arc.nextarc=null; arcnode pre = null; arcnode temp=graph.graph[i].firstarc; if(temp==null){//頂點之前無邊 graph.graph[i].firstarc=arc; System.out.println(graph.graph[i].name+"到"+name+"新增成功"); break; } while(temp!=null)//頂點之前無邊 { pre=temp; temp=temp.nextarc; } System.out.println(graph.graph[i].name+"到"+name+"新增成功"); pre.nextarc=arc; } } } } return graph;} */ } class arcnode{//arc,網弧節點 int ver=-1;//指向邊結點 int weight=0;//權值 arcnode nextarc=null; } class vexnode//vertex頂點節點 { String name; arcnode firstarc=null;//指向第一條弧節點 } //頂點結點 class Graph{//儲存圖 vexnode[] graph;//一個叫graph的vexnode Graph(int num){ graph=new vexnode[num]; } public String toString(){ String[] names=new String[graph.length]; for(int i=0;i<graph.length;i++) { names[i]=graph[i].name; } for(int i=0;i<graph.length;i++) { arcnode pre = null; arcnode p =graph[i].firstarc; while(p!=null) { names[i]=names[i]+" "+graph[p.ver].name+" "+p.weight; p=p.nextarc; } } String s=""; for(int i=0;i<graph.length;i++) s+=names[i]+"\n"; return s; } } class arc{ String name1=null; String name2=null; int weight; arc(String name1,String name2,int weight){ this.name1=name1; this.name2=name2; this.weight=weight; } }
結果: