迪傑斯特拉(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); }