当前位置:   article > 正文

基于Dijkstra算法,实现求城市之间最短距离_java两个城市间的最短距离

java两个城市间的最短距离

源代码存放在git,其中还有其他算法实现:https://github.com/zhangpei

git地址bisha/dataStructure.git

https://github.com/zhangpeibisha/dataStructure.git
https://github.com/zhangpeibisha/dataStructure.git
https://github.com/zhangpeibisha/dataStructure.git
https://github.com/zhangpeibisha/dataStructure.git

dijkstra算法简单思想:

1.使用两个集合,一个存已经遍历了的节点,一个存还未遍历的节点。集合格式{U(10)}代表起点到U节点距离为10

2.基于广度遍历

3.求解两步走:

第一步,找到还未访问节点,且其中最短路径的节点,并将这个最短路径存入已经遍历的节点。

第二部,通过找到的最短路径节点,去修正其他为访问节点到起点的最短路径。

上代码:

city类:

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. /**
  4. * Create by zhangpe0312@qq.com on 2018/4/22.
  5. */
  6. public class City {
  7. // 城市名字
  8. private String cityName;
  9. // 与该城市邻接的城市
  10. private List<Distance> distance;
  11. public City() {
  12. init();
  13. }
  14. /**
  15. * 初始化这个对象,因为当前城市到当前城市的距离默认为0
  16. */
  17. public void init() {
  18. distance = new ArrayList<>();
  19. distance.add(new Distance(this, this, 0.0));
  20. }
  21. public String getCityName() {
  22. return cityName;
  23. }
  24. public void setCityName(String cityName) {
  25. this.cityName = cityName;
  26. }
  27. public List<Distance> getDistance() {
  28. return distance;
  29. }
  30. public void setDistance(List<Distance> distance) {
  31. this.distance = distance;
  32. }
  33. public City addDistance(City toCity) {
  34. this.distance.add(new Distance(this, toCity));
  35. return this;
  36. }
  37. public City addDistance(City toCity, double distance) {
  38. this.distance.add(new Distance(this, toCity, distance));
  39. return this;
  40. }
  41. }

Distance类:

  1. /**
  2. * Create by zhangpe0312@qq.com on 2018/4/22.
  3. *
  4. * 此为原始路径距离
  5. */
  6. public class Distance {
  7. // 起点城市
  8. private City fromCity;
  9. // 目的城市
  10. private City toCity;
  11. // 两个城市之间的距离 为空则为无穷大
  12. private double distance = Integer.MAX_VALUE-1;
  13. public Distance(City fromCity, City toCity) {
  14. this.fromCity = fromCity;
  15. this.toCity = toCity;
  16. }
  17. public Distance(City fromCity, City toCity, double distance) {
  18. this.fromCity = fromCity;
  19. this.toCity = toCity;
  20. this.distance = distance;
  21. }
  22. public City getFromCity() {
  23. return fromCity;
  24. }
  25. public void setFromCity(City fromCity) {
  26. this.fromCity = fromCity;
  27. }
  28. public City getToCity() {
  29. return toCity;
  30. }
  31. public void setToCity(City toCity) {
  32. this.toCity = toCity;
  33. }
  34. public Double getDistance() {
  35. return distance;
  36. }
  37. public void setDistance(Double distance) {
  38. this.distance = distance;
  39. }
  40. }

ShortPath类:

  1. /**
  2. * Create by zhangpe0312@qq.com on 2018/4/22.
  3. *
  4. * 城市与城市之间的最短路径
  5. */
  6. public class ShortPath {
  7. // 出发城市
  8. private City fromCity;
  9. // 目的城市
  10. private City toCity;
  11. // 途径地
  12. private Queue<City> ways;
  13. // 两个城市之间的需要走的距离
  14. private Double distance;
  15. public ShortPath(City fromCity, City toCity) {
  16. this.fromCity = fromCity;
  17. this.toCity = toCity;
  18. }
  19. public City getFromCity() {
  20. return fromCity;
  21. }
  22. public void setFromCity(City fromCity) {
  23. this.fromCity = fromCity;
  24. }
  25. public City getToCity() {
  26. return toCity;
  27. }
  28. public void setToCity(City toCity) {
  29. this.toCity = toCity;
  30. }
  31. public Queue<City> getWays() {
  32. return ways;
  33. }
  34. public void setWays(Queue<City> ways) {
  35. this.ways = ways;
  36. }
  37. public Double getDistance() {
  38. return distance;
  39. }
  40. public void setDistance(Double distance) {
  41. this.distance = distance;
  42. }
  43. }

Dijkstra类:

  1. import java.util.LinkedList;
  2. import java.util.List;
  3. import java.util.Queue;
  4. /**
  5. * Create by zhangpe0312@qq.com on 2018/4/22.
  6. * <p>
  7. * 具体算法
  8. */
  9. public class CityDijKstra {
  10. // 起点城市
  11. private final City startCity;
  12. private final City endCity;
  13. // 使用邻接矩阵表示地图
  14. private List<City> map;
  15. // 求出来的最短路径结果保存,若为空则没有路径可达
  16. private ShortPath shortPath;
  17. public CityDijKstra(City startCity, City endCity, List<City> map) {
  18. this.startCity = startCity;
  19. this.endCity = endCity;
  20. this.map = map;
  21. init();
  22. }
  23. private void dijkstra(int citySize, int startIndex, int endIndex) {
  24. // 保存起点城市到其他城市的最短长度
  25. double[] shortPath = new double[citySize];
  26. // 标记城市是否被求的最短路径
  27. boolean[] marked = new boolean[citySize];
  28. // 保存最短路径访问
  29. Queue<City>[] paths = new LinkedList[citySize];
  30. // 起点和其他点的距离
  31. List<Distance> startDistance = map.get(startIndex).getDistance();
  32. //初始化paths
  33. for (int i = 0; i < citySize; i++) {
  34. Queue<City> queue = new LinkedList<>();
  35. queue.offer(startCity);
  36. queue.offer(map.get(i));
  37. paths[i] = queue;
  38. }
  39. // 自己访问自己距离为0 且不必在求最短路径,因此标记为true
  40. shortPath[startIndex] = 0;
  41. marked[startIndex] = true;
  42. for (int i = 1; i < citySize; i++) {
  43. /**
  44. * 此部分计算起点到其他为标记点中最短路径的那个点
  45. */
  46. // 记录顶点能到达点的最短距离的下标
  47. int k = -1;
  48. // 距离为Integer.MAX_VALUE表示不可达
  49. double mind = Integer.MAX_VALUE;
  50. for (int j = 0; j < citySize; j++) {
  51. double dis = startDistance.get(j).getDistance();
  52. if (!marked[j] && dis < mind) {
  53. mind = dis;
  54. k = j;
  55. }
  56. }
  57. shortPath[k] = mind;
  58. marked[k] = true;
  59. /**
  60. * 此部分根据k点修正起点到其他所有节点的前驱节点及距离
  61. */
  62. for (int j = 0; j < citySize; j++) {
  63. //起点到k点的最短距离 + k点到j点的最短距离
  64. double dis = startDistance.get(k).getDistance() +
  65. map.get(k).getDistance().get(j).getDistance();
  66. // 判断j点是否被标记,若没有被标记,且dis小于直达距离,则修正最短距离
  67. if (!marked[j] && dis < startDistance.get(j).getDistance()) {
  68. map.get(startIndex)
  69. .getDistance()
  70. .get(j).setDistance(dis);
  71. Queue<City> queue = new LinkedList<>();
  72. for (City city : paths[k]) {
  73. queue.offer(city);
  74. }
  75. queue.offer(map.get(j));
  76. paths[j] = queue;
  77. }
  78. }
  79. }
  80. display(shortPath, paths);
  81. this.shortPath.setDistance(shortPath[endIndex]);
  82. this.shortPath.setWays(paths[endIndex]);
  83. }
  84. private void init() {
  85. // 初始化最短路径结果中的起始城市和目的城市
  86. shortPath = new ShortPath(startCity, endCity);
  87. int citySize = map.size();
  88. int startIndex = map.indexOf(startCity);
  89. int endIndex = map.indexOf(endCity);
  90. dijkstra(citySize, startIndex, endIndex);
  91. display(map);
  92. }
  93. private void display(double[] dis, Queue<City>[] paths) {
  94. for (int i = 0; i < dis.length; i++) {
  95. System.out.print(startCity.getCityName() + "到" + map.get(i).getCityName());
  96. System.out.print("的距离为:" + dis[i]);
  97. System.out.println();
  98. System.out.print(startCity.getCityName() + "到" + map.get(i).getCityName());
  99. System.out.print("的路径为:");
  100. for (City city : paths[i]) {
  101. System.out.print(city.getCityName() + " ");
  102. }
  103. System.out.println();
  104. }
  105. }
  106. private void display(List<City> cities){
  107. System.out.println("==========================");
  108. for (City city : cities) {
  109. for (int i = 0; i <city.getDistance().size() ; i++) {
  110. System.out.print(city.getCityName() + "到");
  111. if (city.getDistance().get(i).getDistance() < Integer.MAX_VALUE/2)
  112. System.out.print(city.getDistance().get(i).getToCity().getCityName() +
  113. "距离为" +
  114. city.getDistance().get(i).getDistance());
  115. else
  116. System.out.print(city.getDistance().get(i).getToCity().getCityName() +
  117. "距离为不可达");
  118. System.out.println();
  119. }
  120. }
  121. }
  122. }

测试类:ShortPahtTest:

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. /**
  4. * Create by zhangpe0312@qq.com on 2018/4/22.
  5. * <p>
  6. * 最短路径算法测试
  7. */
  8. public class ShortPathTest {
  9. public static void main(String[] args) {
  10. double MAX = Integer.MAX_VALUE;
  11. City chongqing = new City();
  12. chongqing.setCityName("重庆0");
  13. City guangzhou = new City();
  14. guangzhou.setCityName("广州1");
  15. City shenzheng = new City();
  16. shenzheng.setCityName("深圳2");
  17. City huizhou = new City();
  18. huizhou.setCityName("惠州3");
  19. City shanghai = new City();
  20. shanghai.setCityName("上海4");
  21. chongqing.addDistance(guangzhou,10.0)
  22. .addDistance(shenzheng)
  23. .addDistance(huizhou,30.0)
  24. .addDistance(shanghai,100.0);
  25. guangzhou.addDistance(chongqing)
  26. .addDistance(shenzheng,50.0)
  27. .addDistance(huizhou)
  28. .addDistance(shanghai);
  29. shenzheng.addDistance(guangzhou)
  30. .addDistance(chongqing)
  31. .addDistance(huizhou)
  32. .addDistance(shanghai,10.0);
  33. huizhou.addDistance(guangzhou)
  34. .addDistance(shenzheng,20.0)
  35. .addDistance(chongqing)
  36. .addDistance(shanghai,60.0);
  37. shanghai.addDistance(guangzhou)
  38. .addDistance(shenzheng)
  39. .addDistance(huizhou)
  40. .addDistance(chongqing);
  41. List<City> cities = new ArrayList<City>();
  42. cities.add(chongqing);
  43. cities.add(guangzhou);
  44. cities.add(shenzheng);
  45. cities.add(huizhou);
  46. cities.add(shanghai);
  47. CityDijKstra cityDijKstra = new CityDijKstra(chongqing,shenzheng,cities);
  48. }
  49. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/711098
推荐阅读
相关标签
  

闽ICP备14008679号