1. 程式人生 > >迪傑斯特拉(dijkstra)演算法計算兩個地鐵站最短距離

迪傑斯特拉(dijkstra)演算法計算兩個地鐵站最短距離

private static HashMap<station> resultMap = new HashMap<>();//結果集   private static List<station> analysisList = new ArrayList<>();//分析過的站點  /**   * <b><code>Station</code></b>   * <p/>   * Description:   * <p/>   * <b>Creation Time:</b> 2018/7/19 16:40.   *   * @author huweihui   * @since metrodev2 0.1.0   */  public class Station {      private String name;      private String line;      private List<Station> linkStations = new ArrayList<>();        public String getName() {          return name;      }        public void setName(String name) {          this.name = name;      }        public String getLine() {          return line;      }        public void setLine(String line) {          this.line = line;      }        public List<Station> getLinkStations() {          return linkStations;      }        public void setLinkStations(List<Station> linkStations) {          this.linkStations = linkStations;      }        public Station(String name, String line) {          this.name = name;          this.line = line;      }        public Station(String name) {          this.name = name;      }        public Station (){        }        @Override      public boolean equals(Object obj) {          if(this == obj){              return true;          } else if(obj instanceof Station){              Station s = (Station) obj;              if(s.getName().equals(this.getName())){                  return true;              } else {                  return false;              }          } else {              return false;          }      }        @Override      public int hashCode() {          return this.getName().hashCode();      }        @Override      public String toString() {          return "Station{" +                  "name='" + name + '\'' +                  ", line='" + line + '\'' +                  ", linkStations=" + linkStations +                  '}';      }  }  

/**  * <b><code>Result</code></b>  * <p/>  * Description:  * <p/>  * <b>Creation Time:</b> 2018/7/24 14:56.  *  * @author huweihui  * @since metrodev2 0.1.0  */ public class Result {     private Station star;     private Station end;     private Double distance = 0.0D;     private List<Station> passStations = new ArrayList<>();

    public Station getStar() {         return star;     }

    public void setStar(Station star) {         this.star = star;     }

    public Station getEnd() {         return end;     }

    public void setEnd(Station end) {         this.end = end;     }

    public Double getDistance() {         return distance;     }

    public void setDistance(Double distance) {         this.distance = distance;     }

    public List<Station> getPassStations() {         return passStations;     }

    public void setPassStations(List<Station> passStations) {         this.passStations = passStations;     }

    public Result(Station star, Station end, Double distance) {         this.star = star;         this.end = end;         this.distance = distance;     }

    public Result(){

    }

    @Override     public String toString() {         return "Result{" +                 "star=" + star +                 ", end=" + end +                 ", distance=" + distance +                 ", passStations=" + passStations +                 '}';     } }  

/**  * <b><code>com.richstonedt.metro.app.DataBuilder</code></b>  * <p/>  * Description:  * <p/>  * <b>Creation Time:</b> 2018/7/10 12:36.  *  * @author huweihui  * @since metro-dev 0.1.0  */ public class DataBuilder {

    public static List<Station> line1 = new ArrayList<Station>();     public static List<Station> line2 = new ArrayList<Station>();     public static List<Station> line3 = new ArrayList<Station>();     public static List<Station> line3N = new ArrayList<Station>();     public static List<Station> line4 = new ArrayList<Station>();     public static List<Station> line5 = new ArrayList<Station>();     public static List<Station> line6 = new ArrayList<Station>();     public static List<Station> line7 = new ArrayList<Station>();     public static List<Station> line8 = new ArrayList<Station>();     public static List<Station> line9 = new ArrayList<Station>();     public static List<Station> line13 = new ArrayList<Station>();     public static List<Station> line14 = new ArrayList<Station>();     public static List<Station> lineAPM = new ArrayList<Station>();//APM     public static List<Station> lineGF = new ArrayList<Station>();//廣佛線

    public static LinkedHashSet<List<Station>> lineSet = new LinkedHashSet<>();//所有線集合

    public static int totalStaion = 0;//總的站點數量

    private DataBuilder(){

    }

    public static void init (String lineStr,List<Station> line,String lineName){     }

    private static void getLine(String lineStr,List<Station> line,String lineName){         String[] lineArr = lineStr.split(",");         for (String s : lineArr) {             line.add(new Station(s,lineName));         }     }

    static {         String line1Str = "西朗,坑口,花地灣,芳村,黃沙,長壽路,陳家祠,西門口,公園前,農講所,烈士陵園,東山口,楊箕,體育西路,體育中心,廣州東站";         String line2Str = "廣州南站,石壁,會江,南浦,洛溪,南洲,東曉南,江泰路,昌崗,江南西,市二宮,海珠廣場,公園前,紀念堂,越秀公園,廣州火車站,三元里,飛翔公園,白雲公園,白雲文化廣場,蕭崗,江夏,黃邊,嘉禾望崗";         String line3Str = "番禺廣場,市橋,漢溪長隆,大石,廈滘,瀝滘,大塘,客村,廣州塔,珠江新城,體育西路,石牌橋,崗頂,華師,五山,天河客運站";         String line3NStr = "體育西路,林和西,廣州東站,燕塘,梅花園,京溪南方醫院,同和,永泰,白雲大道北,嘉禾望崗,龍歸,人和,高增,機場南,機場北";         String line4Str = "南沙客運港,南橫,塘坑,大湧,廣隆,飛沙角,金洲,蕉門,黃閣,黃閣汽車城,慶盛,東湧,低湧,海傍,石碁,新造,大學城南,大學城北,官洲,萬勝圍,車陂南,車陂,黃村";         String line5Str = "滘口,坦尾,中山八,西場,西村,廣州火車站,小北,淘金,區莊,動物園,楊箕,五羊邨,珠江新城,獵德,潭村,員村,科韻路,車陂南,東圃,三溪,魚珠,大沙地,大沙東,文衝";         String line6Str = "潯峰崗,橫沙,沙貝,河沙,坦尾,如意坊,黃沙,文化公園,一德路,海珠廣場,北京路,團一大廣場,團一大廣場,東湖,東山口,區莊,黃花崗,沙河頂,天平架,燕塘,天河客運站,長湴,植物園,龍洞,柯木塱,高塘石,黃陂,金峰,暹崗,蘇元,蘿崗,香雪";         String line7Str = "廣州南站,石壁,謝村,鍾村,漢溪長隆,南村萬博,員崗,板橋,大學城南";         String line8Str = "鳳凰新村,沙園,寶崗大道,昌崗,曉港,中大,鷺江,客村,赤崗,磨碟沙,新港東,琶洲,萬勝圍";         String line9Str = "飛鵝嶺,花都汽車城,廣州北站,花城路,花果山公園,花都廣場,馬鞍山公園,蓮塘,清布,清塘,高增";         String line13Str = "魚珠,裕豐圍,雙崗,南海神廟,夏園,南崗,沙村,白江,新塘,官湖,新沙";         String line14Str = "新和,紅衛,新南,楓下,知識城,何棠下,旺村,湯村,鎮龍北,鎮龍";         String lineAPMStr = "廣州塔,海心沙,大劇院,花城大道,婦兒中心,黃埔大道,天河南,體育中心南,林和西";         String lineGFStr = "新城東,東平,世紀蓮,瀾石,魁奇路,季華園,同濟路,祖廟,普君北路,朝安,桂城,南桂路,礌崗,千燈湖,金融高新區,龍溪,菊樹,西朗,鶴洞,沙湧,沙園,燕崗";

        getLine(line1Str,line1,"line1");         getLine(line2Str,line2,"line2");         getLine(line3Str,line3,"line3");         getLine(line3NStr,line3N,"line3N");         getLine(line4Str,line4,"line4");         getLine(line5Str,line5,"line5");         getLine(line6Str,line6,"line6");         getLine(line7Str,line7,"line7");         getLine(line8Str,line8,"line8");         getLine(line9Str,line9,"line9");         getLine(line13Str,line13,"line13");         getLine(line14Str,line14,"line14");         getLine(lineAPMStr,lineAPM,"lineAPM");         getLine(lineGFStr,lineGF,"lineGF");

        lineSet.add(line1);         lineSet.add(line2);         lineSet.add(line3);         lineSet.add(line3N);         lineSet.add(line4);         lineSet.add(line5);         lineSet.add(line6);         lineSet.add(line7);         lineSet.add(line8);         lineSet.add(line9);         lineSet.add(line13);         lineSet.add(line14);         lineSet.add(lineAPM);         lineSet.add(lineGF);

        totalStaion = line1.size() + line2.size() + line3.size() + line4.size() + line5.size() + line6.size()         + line7.size()+line8.size()+line9.size()+line13.size()+line14.size()+lineAPM.size()+lineGF.size();         System.out.println("總的站點數量:" + totalStaion);     } }

  private static List<Station> getLinkStations(Station station) {         List<Station> linkedStaions = new ArrayList<Station>();         for (List<Station> line : SZDataBuilder.lineSet) {             for (int i = 0; i < line.size() ; i++) {                 if (station.equals(line.get(i))) {                     if (i == 0) {                         linkedStaions.add(line.get(i + 1));                     } else if (i == (line.size()-1) ) {                         linkedStaions.add(line.get(i - 1));                     }else {                         linkedStaions.add(line.get(i+1));                         linkedStaions.add(line.get(i-1));                     }                 }             }         }         return linkedStaions;     }  

//通過計算最小權值 計算下一個需要分析的點     private static Station getNextStation() {         Double min = Double.MAX_VALUE;         Station rets = null;         Set<Station> stations = resultMap.keySet();         for (Station station : stations) {             if (analysisList.contains(station)) {                 continue;             }             Result result = resultMap.get(station);             if (result.getDistance() < min) {                 min = result.getDistance();                 rets = result.getEnd();             }         }         return rets;     }     public static Result calculate(Station star, Station end) {         if (!analysisList.contains(star)) {             analysisList.add(star);         }         if (star.equals(end)){             Result result = new Result();             result.setDistance(0.0D);             result.setEnd(star);             result.setStar(star);             resultMap.put(star, result);             return resultMap.get(star);         }         if (resultMap.isEmpty()) {             List<Station> linkStations = getLinkStations(star);             for (Station station : linkStations) {                 Result result = new Result();                 result.setStar(star);                 result.setEnd(station);                 String key = star.getName() + ":" + station.getName();                 Double distance = DistanceBuilder.getDistance(key);                 result.setDistance(distance);                 result.getPassStations().add(station);                 resultMap.put(station, result);             }         }         Station parent = getNextStation();         if (parent==null){             Result result = new Result();             result.setDistance(0.0D);             result.setStar(star);             result.setEnd(end);             return resultMap.put(end, result);         }         if (parent.equals(end)) {             return resultMap.get(parent);         }         List<Station> childLinkStations = getLinkStations(parent);         for (Station child : childLinkStations) {             if (analysisList.contains(child)) {                 continue;             }             String key = parent.getName() + ":" + child.getName();             Double distance = DistanceBuilder.getDistance(key);             if( parent.getName().equals(child.getName())){                 distance = 0.0D;             }             Double parentDistance = resultMap.get(parent).getDistance();             distance = doubleAdd(distance, parentDistance);             List<Station> parentPassStations = resultMap.get(parent).getPassStations();             Result childResult = resultMap.get(child);             if (childResult!=null){                 if (childResult.getDistance() > distance) {                     childResult.setDistance(distance);                     childResult.getPassStations().clear();                     childResult.getPassStations().addAll(parentPassStations);                     childResult.getPassStations().add(child);                 }             }else {                 childResult = new Result();                 childResult.setDistance(distance);                 childResult.setStar(star);                 childResult.setEnd(child);                 childResult.getPassStations().addAll(parentPassStations);                 childResult.getPassStations().add(child);             }             resultMap.put(child, childResult);         }         analysisList.add(parent);         calculate(star, end);         return resultMap.get(end);     }