最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實現Dijkstra輸出最短路徑的實例

 更新時間:2017年09月22日 15:04:41   投稿:lqh  
這篇文章主要介紹了Java實現Dijkstra輸出最短路徑的實例的相關資料,希望通過本文能幫助到大家,需要的朋友可以參考下

Java實現Dijkstra輸出指定起點到終點的最短路徑

前言:

最近在公司參加了一個比賽,其中涉及的一個問題,可以簡化成如是描述:一個二維矩陣,每個點都有權重,需要找出從指定起點到終點的最短路徑。

馬上就想到了Dijkstra算法,所以又重新溫故了一遍,這里給出Java的實現。

而輸出最短路徑的時候,在網上也進行了查閱,沒發(fā)現什么標準的方法,于是在下面的實現中,我給出了一種能夠想到的比較精簡的方式:利用prev[]數組進行遞歸輸出。

package graph.dijsktra; 
 
import graph.model.Point; 
 
import java.util.*; 
 
/** 
 * Created by MHX on 2017/9/13. 
 */ 
public class Dijkstra { 
  private int[][] map; // 地圖結構保存 
  private int[][] edges; // 鄰接矩陣 
  private int[] prev; // 前驅節(jié)點標號 
  private boolean[] s; // S集合中存放到起點已經算出最短路徑的點 
  private int[] dist; // dist[i]表示起點到第i個節(jié)點的最短路徑 
  private int pointNum; // 點的個數 
  private Map<Integer, Point> indexPointMap; // 標號和點的對應關系 
  private Map<Point, Integer> pointIndexMap; // 點和標號的對應關系 
  private int v0; // 起點標號 
  private Point startPoint; // 起點 
  private Point endPoint; // 終點 
  private Map<Point, Point> pointPointMap; // 保存點和權重的映射關系 
  private List<Point> allPoints; // 保存所有點 
  private int maxX; // x坐標的最大值 
  private int maxY; // y坐標的最大值 
 
  public Dijkstra(int map[][], Point startPoint, Point endPoint) { 
    this.maxX = map.length; 
    this.maxY = map[0].length; 
    this.pointNum = maxX * maxY; 
    this.map = map; 
    this.startPoint = startPoint; 
    this.endPoint = endPoint; 
    init(); 
    dijkstra(); 
  } 
 
  /** 
   * 打印指定起點到終點的最短路徑 
   */ 
  public void printShortestPath() { 
    printDijkstra(pointIndexMap.get(endPoint)); 
  } 
 
  /** 
   * 初始化dijkstra 
   */ 
  private void init() { 
    // 初始化所有變量 
    edges = new int[pointNum][pointNum]; 
    prev = new int[pointNum]; 
    s = new boolean[pointNum]; 
    dist = new int[pointNum]; 
    indexPointMap = new HashMap<>(); 
    pointIndexMap = new HashMap<>(); 
    pointPointMap = new HashMap<>(); 
    allPoints = new ArrayList<>(); 
 
    // 將map二維數組中的所有點轉換成自己的結構 
    int count = 0; 
    for (int x = 0; x < maxX; ++x) { 
      for (int y = 0; y < maxY; ++y) { 
        indexPointMap.put(count, new Point(x, y)); 
        pointIndexMap.put(new Point(x, y), count); 
        count++; 
        allPoints.add(new Point(x, y)); 
        pointPointMap.put(new Point(x, y), new Point(x, y, map[x][y])); 
      } 
    } 
 
    // 初始化鄰接矩陣 
    for (int i = 0; i < pointNum; ++i) { 
      for (int j = 0; j < pointNum; ++j) { 
        if (i == j) { 
          edges[i][j] = 0; 
        } else { 
          edges[i][j] = 9999; 
        } 
      } 
    } 
 
    // 根據map上的權重初始化edges,當然這種算法是沒有單獨加起點的權重的 
    for (Point point : allPoints) { 
      for (Point aroundPoint : getAroundPoints(point)) { 
        edges[pointIndexMap.get(point)][pointIndexMap.get(aroundPoint)] = aroundPoint.getValue(); 
      } 
    } 
 
    v0 = pointIndexMap.get(startPoint); 
 
    for (int i = 0; i < pointNum; ++i) { 
      dist[i] = edges[v0][i]; 
      if (dist[i] == 9999) { 
        // 如果從0點(起點)到i點最短路徑是9999,即不可達 
        // 則i節(jié)點的前驅節(jié)點不存在 
        prev[i] = -1; 
      } else { 
        // 初始化i節(jié)點的前驅節(jié)點為起點,因為這個時候有最短路徑的都是與起點直接相連的點 
        prev[i] = v0; 
      } 
    } 
 
    dist[v0] = 0; 
    s[v0] = true; 
  } 
 
  /** 
   * dijkstra核心算法 
   */ 
  private void dijkstra() { 
    for (int i = 1; i < pointNum; ++i) { // 此時有pointNum - 1個點在U集合中,需要循環(huán)pointNum - 1次 
      int minDist = 9999; 
      int u = v0; 
 
      for (int j = 1; j < pointNum; ++j) { // 在U集合中,找到到起點最短距離的點 
        if (!s[j] && dist[j] < minDist) { // 不在S集合,就是在U集合 
          u = j; 
          minDist = dist[j]; 
        } 
      } 
      s[u] = true; // 將這個點放入S集合 
 
      for (int j = 1; j < pointNum; ++j) { // 以當前剛從U集合放入S集合的點u為基礎,循環(huán)其可以到達的點 
        if (!s[j] && edges[u][j] < 9999) { 
          if (dist[u] + edges[u][j] < dist[j]) { 
            dist[j] = dist[u] + edges[u][j]; 
            prev[j] = u; 
          } 
        } 
      } 
    } 
  } 
 
  private void printDijkstra(int endPointIndex) { 
    if (endPointIndex == v0) { 
      System.out.print(indexPointMap.get(v0) + ","); 
      return; 
    } 
    printDijkstra(prev[endPointIndex]); 
    System.out.print(indexPointMap.get(endPointIndex) + ","); 
  } 
 
  private List<Point> getAroundPoints(Point point) { 
    List<Point> aroundPoints = new ArrayList<>(); 
    int x = point.getX(); 
    int y = point.getY(); 
    aroundPoints.add(pointPointMap.get(new Point(x - 1, y))); 
    aroundPoints.add(pointPointMap.get(new Point(x, y + 1))); 
    aroundPoints.add(pointPointMap.get(new Point(x + 1, y))); 
    aroundPoints.add(pointPointMap.get(new Point(x, y - 1))); 
    aroundPoints.removeAll(Collections.singleton(null)); // 剔除不在地圖范圍內的null點 
    return aroundPoints; 
  } 
 
  public static void main(String[] args) { 
    int map[][] = { 
        {1, 2, 2, 2, 2, 2, 2}, 
        {1, 0, 2, 2, 0, 2, 2}, 
        {1, 2, 0, 2, 0, 2, 2}, 
        {1, 2, 2, 0, 2, 0, 2}, 
        {1, 2, 2, 2, 2, 2, 2}, 
        {1, 1, 1, 1, 1, 1, 1} 
    }; // 每個點都代表權重,沒有方向限制 
    Point startPoint = new Point(0, 3); // 起點 
    Point endPoint = new Point(5, 6); // 終點 
    Dijkstra dijkstra = new Dijkstra(map, startPoint, endPoint); 
    dijkstra.printShortestPath(); 
  } 
} 
package graph.model; 
 
public class Point { 
  private int x; 
  private int y; 
  private int value; 
 
  public Point(int x, int y) { 
    this.x = x; 
    this.y = y; 
  } 
 
  public Point(int x, int y, int value) { 
    this.x = x; 
    this.y = y; 
    this.value = value; 
  } 
 
  public int getX() { 
    return x; 
  } 
 
  public void setX(int x) { 
    this.x = x; 
  } 
 
  public int getY() { 
    return y; 
  } 
 
  public void setY(int y) { 
    this.y = y; 
  } 
 
  public int getValue() { 
    return value; 
  } 
 
  public void setValue(int value) { 
    this.value = value; 
  } 
 
  @Override 
  public String toString() { 
    return "{" + 
        "x=" + x + 
        ", y=" + y + 
        '}'; 
  } 
 
  @Override 
  public boolean equals(Object o) { 
    if (this == o) return true; 
    if (o == null || getClass() != o.getClass()) return false; 
 
    Point point = (Point) o; 
 
    if (x != point.x) return false; 
    return y == point.y; 
  } 
 
  @Override 
  public int hashCode() { 
    int result = x; 
    result = 31 * result + y; 
    return result; 
  } 
} 

如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望通過本文能幫助到大家,謝謝大家對本站的支持!

相關文章

  • 基于ArrayList常用方法的源碼全面解析

    基于ArrayList常用方法的源碼全面解析

    下面小編就為大家?guī)硪黄贏rrayList常用方法的源碼全面解析。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • java應用程序如何自定義log4j配置文件的位置

    java應用程序如何自定義log4j配置文件的位置

    這篇文章主要介紹了java應用程序如何自定義log4j配置文件的位置,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • java對xml節(jié)點屬性的增刪改查實現方法

    java對xml節(jié)點屬性的增刪改查實現方法

    下面小編就為大家?guī)硪黄猨ava對xml節(jié)點屬性的增刪改查實現方法。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-10-10
  • SpringCache源碼解析Annotation案例講解

    SpringCache源碼解析Annotation案例講解

    這篇文章主要介紹了SpringCache源碼解析Annotation的相關知識,本文通過案例講解的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • Java并發(fā)編程之CountDownLatch原理詳解

    Java并發(fā)編程之CountDownLatch原理詳解

    這篇文章主要介紹了Java并發(fā)編程之CountDownLatch原理詳解,CountDownLatch類中使用了一個繼承自AQS的共享鎖Sync對象,構造CountDownLatch對象時會將傳入的線程數值設為AQS的state值,需要的朋友可以參考下
    2023-12-12
  • Maven添加reactor依賴失敗的解決方案

    Maven添加reactor依賴失敗的解決方案

    起初是自己在學spring boot3,結果到了reactor這一部分的時候,在項目的pom.xml文件中添加下列依賴報錯,接下來通過本文給大家介紹Maven添加reactor依賴失敗的解決方案,需要的朋友可以參考下
    2024-06-06
  • 搭建MyBatis-Plus框架并進行數據庫增刪改查功能

    搭建MyBatis-Plus框架并進行數據庫增刪改查功能

    這篇文章主要介紹了搭建MyBatis-Plus框架并進行數據庫增刪改查,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • Spring-AOP @AspectJ進階之如何綁定代理對象

    Spring-AOP @AspectJ進階之如何綁定代理對象

    這篇文章主要介紹了Spring-AOP @AspectJ進階之如何綁定代理對象的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Intellij IDEA集成JProfiler性能分析工具

    Intellij IDEA集成JProfiler性能分析工具

    作為Java程序員,性能分析是我們必須掌握的技能之一,在性能分析中,JProfiler是一款非常強大的工具,本文就來介紹一下Intellij IDEA集成JProfiler性能分析工具,就有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • Spring Boot集成LangChain來實現Rag應用的問題小結

    Spring Boot集成LangChain來實現Rag應用的問題小結

    檢索增強生成(RAG)是一種優(yōu)化大型語言模型(LLM)輸出的技術,通過引用權威知識庫以增強模型的準確性和相關性,RAG允許LLM在不重新訓練的情況下訪問特定領域的知識,提高了其在各種應用中的實用性和信任度,感興趣的朋友跟隨小編一起看看吧
    2024-09-09

最新評論

通州区| 鄄城县| 延长县| 靖边县| 正定县| 文安县| 许昌县| 湘阴县| 梁山县| 泰兴市| 健康| 越西县| 读书| 岳池县| 南安市| 斗六市| 新化县| 扎兰屯市| 太仓市| 顺义区| 乐至县| 本溪市| 拉萨市| 东丰县| 永登县| 上杭县| 遵义县| 孙吴县| 苍梧县| 育儿| 鄄城县| 财经| 上杭县| 思南县| 库车县| 大庆市| 三门峡市| 林芝县| 定州市| 交城县| 庆元县|