日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Dijkstra算法求最短路径(java)

發(fā)布時間:2025/1/21 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Dijkstra算法求最短路径(java) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
任務(wù)描述:在一個無向圖中,獲取起始節(jié)點到所有其他節(jié)點的最短路徑描述

Dijkstra(迪杰斯特拉)算法是典型的最短路徑路由算法,用于計算一個節(jié)點到其他所有節(jié)點的最短路徑。主要特點是以起始點為中心向外層層擴展,直到擴展到終點為止。

Dijkstra一般的表述通常有兩種方式,一種用永久和臨時標號方式,一種是用OPEN, CLOSE表方式
用OPEN,CLOSE表的方式,其采用的是貪心法的算法策略,大概過程如下:
1.聲明兩個集合,open和close,open用于存儲未遍歷的節(jié)點,close用來存儲已遍歷的節(jié)點
2.初始階段,將初始節(jié)點放入close,其他所有節(jié)點放入open
3.以初始節(jié)點為中心向外一層層遍歷,獲取離指定節(jié)點最近的子節(jié)點放入close并從新計算路徑,直至close包含所有子節(jié)點

代碼實例如下:
Node對象用于封裝節(jié)點信息,包括名字和子節(jié)點
[java]?view plaincopy
  • public?class?Node?{??
  • ????private?String?name;??
  • ????private?Map<Node,Integer>?child=new?HashMap<Node,Integer>();??
  • ????public?Node(String?name){??
  • ????????this.name=name;??
  • ????}??
  • ????public?String?getName()?{??
  • ????????return?name;??
  • ????}??
  • ????public?void?setName(String?name)?{??
  • ????????this.name?=?name;??
  • ????}??
  • ????public?Map<Node,?Integer>?getChild()?{??
  • ????????return?child;??
  • ????}??
  • ????public?void?setChild(Map<Node,?Integer>?child)?{??
  • ????????this.child?=?child;??
  • ????}??
  • }??

  • MapBuilder用于初始化數(shù)據(jù)源,返回圖的起始節(jié)點
    [java]?view plaincopy
  • public?class?MapBuilder?{??
  • ????public?Node?build(Set<Node>?open,?Set<Node>?close){??
  • ????????Node?nodeA=new?Node("A");??
  • ????????Node?nodeB=new?Node("B");??
  • ????????Node?nodeC=new?Node("C");??
  • ????????Node?nodeD=new?Node("D");??
  • ????????Node?nodeE=new?Node("E");??
  • ????????Node?nodeF=new?Node("F");??
  • ????????Node?nodeG=new?Node("G");??
  • ????????Node?nodeH=new?Node("H");??
  • ????????nodeA.getChild().put(nodeB,?1);??
  • ????????nodeA.getChild().put(nodeC,?1);??
  • ????????nodeA.getChild().put(nodeD,?4);??
  • ????????nodeA.getChild().put(nodeG,?5);??
  • ????????nodeA.getChild().put(nodeF,?2);??
  • ????????nodeB.getChild().put(nodeA,?1);??
  • ????????nodeB.getChild().put(nodeF,?2);??
  • ????????nodeB.getChild().put(nodeH,?4);??
  • ????????nodeC.getChild().put(nodeA,?1);??
  • ????????nodeC.getChild().put(nodeG,?3);??
  • ????????nodeD.getChild().put(nodeA,?4);??
  • ????????nodeD.getChild().put(nodeE,?1);??
  • ????????nodeE.getChild().put(nodeD,?1);??
  • ????????nodeE.getChild().put(nodeF,?1);??
  • ????????nodeF.getChild().put(nodeE,?1);??
  • ????????nodeF.getChild().put(nodeB,?2);??
  • ????????nodeF.getChild().put(nodeA,?2);??
  • ????????nodeG.getChild().put(nodeC,?3);??
  • ????????nodeG.getChild().put(nodeA,?5);??
  • ????????nodeG.getChild().put(nodeH,?1);??
  • ????????nodeH.getChild().put(nodeB,?4);??
  • ????????nodeH.getChild().put(nodeG,?1);??
  • ????????open.add(nodeB);??
  • ????????open.add(nodeC);??
  • ????????open.add(nodeD);??
  • ????????open.add(nodeE);??
  • ????????open.add(nodeF);??
  • ????????open.add(nodeG);??
  • ????????open.add(nodeH);??
  • ????????close.add(nodeA);??
  • ????????return?nodeA;??
  • ????}??
  • }??
  • 圖的結(jié)構(gòu)如下圖所示:


    Dijkstra對象用于計算起始節(jié)點到所有其他節(jié)點的最短路徑
    [java]?view plaincopy
  • public?class?Dijkstra?{??
  • ????Set<Node>?open=new?HashSet<Node>();??
  • ????Set<Node>?close=new?HashSet<Node>();??
  • ????Map<String,Integer>?path=new?HashMap<String,Integer>();//封裝路徑距離??
  • ????Map<String,String>?pathInfo=new?HashMap<String,String>();//封裝路徑信息??
  • ????public?Node?init(){??
  • ????????//初始路徑,因沒有A->E這條路徑,所以path(E)設(shè)置為Integer.MAX_VALUE??
  • ????????path.put("B",?1);??
  • ????????pathInfo.put("B",?"A->B");??
  • ????????path.put("C",?1);??
  • ????????pathInfo.put("C",?"A->C");??
  • ????????path.put("D",?4);??
  • ????????pathInfo.put("D",?"A->D");??
  • ????????path.put("E",?Integer.MAX_VALUE);??
  • ????????pathInfo.put("E",?"A");??
  • ????????path.put("F",?2);??
  • ????????pathInfo.put("F",?"A->F");??
  • ????????path.put("G",?5);??
  • ????????pathInfo.put("G",?"A->G");??
  • ????????path.put("H",?Integer.MAX_VALUE);??
  • ????????pathInfo.put("H",?"A");??
  • ????????//將初始節(jié)點放入close,其他節(jié)點放入open??
  • ????????Node?start=new?MapBuilder().build(open,close);??
  • ????????return?start;??
  • ????}??
  • ????public?void?computePath(Node?start){??
  • ????????Node?nearest=getShortestPath(start);//取距離start節(jié)點最近的子節(jié)點,放入close??
  • ????????if(nearest==null){??
  • ????????????return;??
  • ????????}??
  • ????????close.add(nearest);??
  • ????????open.remove(nearest);??
  • ????????Map<Node,Integer>?childs=nearest.getChild();??
  • ????????for(Node?child:childs.keySet()){??
  • ????????????if(open.contains(child)){//如果子節(jié)點在open中??
  • ????????????????Integer?newCompute=path.get(nearest.getName())+childs.get(child);??
  • ????????????????if(path.get(child.getName())>newCompute){//之前設(shè)置的距離大于新計算出來的距離??
  • ????????????????????path.put(child.getName(),?newCompute);??
  • ????????????????????pathInfo.put(child.getName(),?pathInfo.get(nearest.getName())+"->"+child.getName());??
  • ????????????????}??
  • ????????????}??
  • ????????}??
  • ????????computePath(start);//重復(fù)執(zhí)行自己,確保所有子節(jié)點被遍歷??
  • ????????computePath(nearest);//向外一層層遞歸,直至所有頂點被遍歷??
  • ????}??
  • ????public?void?printPathInfo(){??
  • ????????Set<Map.Entry<String,?String>>?pathInfos=pathInfo.entrySet();??
  • ????????for(Map.Entry<String,?String>?pathInfo:pathInfos){??
  • ????????????System.out.println(pathInfo.getKey()+":"+pathInfo.getValue());??
  • ????????}??
  • ????}??
  • ????/**?
  • ?????*?獲取與node最近的子節(jié)點?
  • ?????*/??
  • ????private?Node?getShortestPath(Node?node){??
  • ????????Node?res=null;??
  • ????????int?minDis=Integer.MAX_VALUE;??
  • ????????Map<Node,Integer>?childs=node.getChild();??
  • ????????for(Node?child:childs.keySet()){??
  • ????????????if(open.contains(child)){??
  • ????????????????int?distance=childs.get(child);??
  • ????????????????if(distance<minDis){??
  • ????????????????????minDis=distance;??
  • ????????????????????res=child;??
  • ????????????????}??
  • ????????????}??
  • ????????}??
  • ????????return?res;??
  • ????}??
  • }??

  • Main用于測試Dijkstra對象
    [java]?view plaincopy
  • public?class?Main?{??
  • ????public?static?void?main(String[]?args)?{??
  • ????????Dijkstra?test=new?Dijkstra();??
  • ????????Node?start=test.init();??
  • ????????test.computePath(start);??
  • ????????test.printPathInfo();??
  • ????}??
  • }??

  • 打印輸出如下:
    D:A->D
    E:A->F->E
    F:A->F
    G:A->C->G
    B:A->B
    C:A->C
    H:A->B->H

    總結(jié)

    以上是生活随笔為你收集整理的Dijkstra算法求最短路径(java)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。