php构建路径,个人项目——地铁线路规划(示例代码)

public classDijkstra {private static HashMap resultMap = new HashMap<>();private static List analysisList = new ArrayList<>();//存放已经分析过的站点(已被分析表示起始点到该点的最短路径已求出)

public staticResult calculate(Station star, Station end) {if (!analysisList.contains(star)) {

analysisList.add(star);

}//将star站点放到以及分析的站点中去

if(star.equals(end)) {

Result result= newResult();

result.setDistance(0.0D);

result.setEndStation(star);

result.setStarStation(star);returnresultMap.put(star, result);

}//当star站点等于end站点,则设置result的距离为0,end站点为star站点。

if (resultMap.isEmpty()) { //当第一次调用calculate,并且起始点和终止点不同,那么resultMap为空。

List linkStations = getLinkStations(star); //把相邻站点集合中的所有站点,加入resultMap中。

for(Station station : linkStations) {

Result result= newResult();

result.setStarStation(star);

result.setEndStation(station);

String key= star.getName() + ":" +station.getName();

Double distance=Builder.getDistance(key);

result.setDistance(distance);

result.getPassStation().add(station);

resultMap.put(station, result);

}

}

Station parent=getNextStation();if (parent == null) {//如果resultMap所有点keySet被分析完了,则返回的parent为null。

Result result = newResult();

result.setDistance(0.0D);

result.setStarStation(star);

result.setEndStation(end);//put方法的返回值就是value值。

returnresultMap.put(end, result);

}//如果得到的最佳邻点与目标点相同,则直接返回最佳邻点对应的result对象。

if(parent.equals(end)) {returnresultMap.get(parent);

}//分析一个parent最佳点后,把它的相邻点都会加入到resultMap中,在下一次调用getNextStation获取resultMap中未被标记且距离(起始点到该station的距离)最短。

List childLinkStations =getLinkStations(parent);for(Station child : childLinkStations) {if(analysisList.contains(child)) {continue;

}

String key= parent.getName() + ":" +child.getName();

Double distance;

distance=Builder.getDistance(key);

Builder.getDistance(key);if(parent.getName().equals(child.getName())) {

distance= 0.0D;

}

Double parentDistance=resultMap.get(parent).getDistance();

distance=doubleAdd(distance,parentDistance);

List parentPassStations =resultMap.get(parent).getPassStation();

Result childResult=resultMap.get(child);if (childResult != null) {if (childResult.getDistance() > distance) { //如果通过最佳点比直接到距离小,则更新resultMap中的对应result对象。

childResult.setDistance(distance);

childResult.getPassStation().clear();

childResult.getPassStation().addAll(parentPassStations);

childResult.getPassStation().add(child);//路径更新为A->最佳点->child点。

}

}else{//如果在resultMap中没有最佳点的相邻点,则往resultMap中添加通过最佳点(初始为起始点的最佳邻点)到达该点。

childResult = newResult();

childResult.setDistance(distance);

childResult.setStarStation(star);

childResult.setEndStation(child);

childResult.getPassStation().addAll(parentPassStations);

childResult.getPassStation().add(child);

}

resultMap.put(child, childResult);

}

analysisList.add(parent);

calculate(star, end);returnresultMap.get(end);//循环遍历得到最好的结果

}public static voidreMake() {//清空分析点的集合以及结果Map

analysisList.clear();;

resultMap.clear();;

}public static ListgetLinkStations(Station station) {//找出所有的邻接点

List linkedStaions = new ArrayList();for (List line : Builder.lineSet) {//遍历每条地铁线

for (int i = 0; i < line.size(); i++) {if(station.equals(line.get(i))) {if (i == 0) { //如果该站点位于地铁线的起始站,则相邻站为地铁线的第二个站点(i+1),

linkedStaions.add(line.get(i + 1));

}else if (i == (line.size() - 1)) {//如果该站点位于地铁线的最后一个站,则相邻站为地铁线的倒数第二个站点(i-1),

linkedStaions.add(line.get(i - 1));

}else { //如果该站点位于地铁线的其余位置,则相邻站点为该站点前后位置(i-1/i+1)

linkedStaions.add(line.get(i + 1));

linkedStaions.add(line.get(i- 1));

}

}

}

}returnlinkedStaions;

}private staticStation getNextStation() {//计算最小的权重值,计算下一个需要分析的点

Double min=Double.MAX_VALUE;

Station rets= null;

Set stations = resultMap.keySet();//获取resultMap中的station集合

for(Station station : stations) {if (analysisList.contains(station)) {//如果该点被标记为“已被分析”,则跳过分析

continue;

}//循环比较resultMap中未被标记的点,求出最短路径的result对象。

Result result =resultMap.get(station);if (result.getDistance()

min=result.getDistance();

rets=result.getEndStation();

}

}return rets;//返回下一个站点

}private static double doubleAdd(double v1, doublev2) {

BigDecimal b1= newBigDecimal(Double.toString(v1));

BigDecimal b2= newBigDecimal(Double.toString(v2));returnb1.add(b2).doubleValue();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值