北京地铁线路规划

设计:https://www.cnblogs.com/chenjiji/p/11558885.html
GitHub:https://github.com/Dokenhhh/BJSubway
基本需求
1.获取线路站点信息
2.获取两个站点间的最短路径
代码简析
站点与线路信息采用.txt存储
1 //线路名称
刘园:西横堤 1 //站点距离
西横堤:果酒厂 1
果酒厂:本溪路 1
本溪路:勤俭道 1
勤俭道:洪湖里 1
洪湖里:西站 1
西站:西北角 1
西北角:西南角 1
西南角:二纬路 1
二纬路:海光寺 1
......
实体类设定:
Station为站点类,Result为结果类
站点类Station包含变量:站点名、所属地铁线、相邻站点集合。
结果类Result包含变量:起始站、终止站、距离(站台数)、中间经过站点。
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 (){
}
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;
}
}
public int hashCode() {
return this.getName().hashCode();
}
public String toString() {
return "Station{" +
"name='" + name + '\'' +
", line='" + line + '\'' +
", linkStations=" + linkStations +
'}';
}
}
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 +
'}';
}
}
在这里采用Dijkstra算法进行最短路径的查询
public class DijkstraUtil {
private static HashMap<Station, Result> resultMap = new HashMap<>();
private static List<Station> analysisList = new ArrayList<>();
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);
return resultMap.put(star, result);
}
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;
distance = DistanceBuilder.getDistance(key);
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);
return calculate(star, end);
}
public static List<Station> getLinkStations(Station station) {
List<Station> linkedStaions = new ArrayList<Station>();
for (List<Station> line : DistanceBuilder.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;
}
private static double doubleAdd(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
}
以下为测试样例:
java subway -a 1号线 -map subway.txt -o station.txt

java subway -b 万寿路 七里庄 -map subway.txt -o routine.txt
