国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java實現利用廣度優先遍歷(BFS)計算最短路徑的方法

2019-11-26 15:12:48
字體:
來源:轉載
供稿:網友

本文實例講述了Java實現利用廣度優先遍歷(BFS)計算最短路徑的方法。分享給大家供大家參考。具體分析如下:

我們用字符串代表圖的頂點(vertax),來模擬學校中Classroom, Square, Toilet, Canteen, South Gate, North Gate幾個地點,然后計算任意兩點之間的最短路徑。

如下圖所示:

如,我想從North Gate去Canteen, 程序的輸出結果應為:

BFS: From [North Gate] to [Canteen]:North GateSquareCanteen

首先定義一個算法接口Algorithm:

public interface Algorithm {  /**   * 執行算法   */  void perform(Graph g, String sourceVertex);  /**   * 得到路徑   */  Map<String, String> getPath();}

然后,定義圖:

/** * (無向)圖 */public class Graph {  // 圖的起點  private String firstVertax;  // 鄰接表  private Map<String, List<String>> adj = new HashMap<>();  // 遍歷算法  private Algorithm algorithm;  public Graph(Algorithm algorithm) {    this.algorithm = algorithm;  }  /**   * 執行算法   */  public void done() {    algorithm.perform(this, firstVertax);  }  /**   * 得到從起點到{@code vertex}點的最短路徑   * @param vertex   * @return   */  public Stack<String> findPathTo(String vertex) {    Stack<String> stack = new Stack<>();    stack.add(vertex);    Map<String, String> path = algorithm.getPath();    for (String location = path.get(vertex) ; false == location.equals(firstVertax) ; location = path.get(location)) {      stack.push(location);    }    stack.push(firstVertax);    return stack;  }  /**   * 添加一條邊   */  public void addEdge(String fromVertex, String toVertex) {    if (firstVertax == null) {      firstVertax = fromVertex;    }    adj.get(fromVertex).add(toVertex);    adj.get(toVertex).add(fromVertex);  }  /**   * 添加一個頂點   */  public void addVertex(String vertex) {    adj.put(vertex, new ArrayList<>());  }  public Map<String, List<String>> getAdj() {    return adj;  }}

這里我們使用策略設計模式,將算法與Graph類分離,通過在構造Graph對象時傳入一個Algorithm接口的實現來為Graph選擇遍歷算法。

public Graph(Algorithm algorithm) {    this.algorithm = algorithm;  }

無向圖的存儲結構為鄰接表,這里用一個Map表示鄰接表,map的key是學校地點(String),value是一個與該地點相連通的地點表(List<String>)。

// 鄰接表  private Map<String, List<String>> adj = new HashMap<>();

然后,編寫Algorithm接口的BFS實現:

/** * 封裝BFS算法 */public class BroadFristSearchAlgorithm implements Algorithm {  // 保存已經訪問過的地點  private List<String> visitedVertex;  // 保存最短路徑  private Map<String, String> path;  @Override  public void perform(Graph g, String sourceVertex) {    if (null == visitedVertex) {      visitedVertex = new ArrayList<>();    }    if (null == path) {      path = new HashMap<>();    }    BFS(g, sourceVertex);  }  @Override  public Map<String, String> getPath() {    return path;  }  private void BFS(Graph g, String sourceVertex) {    Queue<String> queue = new LinkedList<>();    // 標記起點    visitedVertex.add(sourceVertex);    // 起點入列    queue.add(sourceVertex);    while (false == queue.isEmpty()) {      String ver = queue.poll();      List<String> toBeVisitedVertex = g.getAdj().get(ver);      for (String v : toBeVisitedVertex) {        if (false == visitedVertex.contains(v)) {          visitedVertex.add(v);          path.put(v, ver);          queue.add(v);        }      }    }  }}

其中,path是Map類型,意為從 value 到 key 的一條路徑。

BFS算法描述:

1. 將起點標記為已訪問并放入隊列。
2. 從隊列中取出一個頂點,得到與該頂點相通的所有頂點。
3. 遍歷這些頂點,先判斷頂點是否已被訪問過,如果否,標記該點為已訪問,記錄當前路徑,并將當前頂點入列。
4. 重復2、3,直到隊列為空。

測試用例:

String[] vertex = {"North Gate", "South Gate", "Classroom", "Square", "Toilet", "Canteen"};  Edge[] edges = {      new Edge("North Gate", "Classroom"),      new Edge("North Gate", "Square"),      new Edge("Classroom", "Toilet"),      new Edge("Square", "Toilet"),      new Edge("Square", "Canteen"),      new Edge("Toilet", "South Gate"),      new Edge("Toilet", "South Gate"),  };@Test  public void testBFS() {    Graph g = new Graph(new BroadFristSearchAlgorithm());    addVertex(g);    addEdge(g);    g.done();    Stack<String> result = g.findPathTo("Canteen");    System.out.println("BFS: From [North Gate] to [Canteen]:");    while (!result.isEmpty()) {      System.out.println(result.pop());    }  }

希望本文所述對大家的java程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 古蔺县| 大埔区| 江孜县| 哈密市| 哈巴河县| 晋城| 博兴县| 马山县| 三河市| 阳信县| 诏安县| 常熟市| 连云港市| 林州市| 阿拉善盟| 信丰县| 西林县| 新乐市| 西吉县| 灌南县| 寻乌县| 淮安市| 台南市| 西吉县| 抚顺县| 都昌县| 阿克苏市| 江源县| 宁晋县| 金阳县| 米林县| 青海省| 宣化县| 三原县| 镇平县| 阿克苏市| 芦溪县| 阜南县| 奎屯市| 梨树县| 绵竹市|