北京地铁线路规划

匆匆过客 提交于 2019-12-01 09:38:01

北京地铁线路规划

 设计: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

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!