地图上实现最短路径的查询,据我了解的,一般用Dijkstra算法和A*算法来实现。由于这是一个课程项目,时间比较急,而且自己不熟悉A*算法,所以参考网上的Dijkstra算法(http://blog.csdn.net/javaman_chen/article/details/8254309)的代码来实现了地图上任意两点的最短路径的查询。但该demo存在一个很严重的错误,缺了两行非常关键的代码……

  首先,来了解下Dijkstra算法:无向图的最短路径求解算法之——Dijkstra算法 http://sbp810050504.blog.51cto.com/2799422/690803 。由此可以看出,Dijkstra算法的效率是很低的,它遍历的点很多,要以起始点为中心向外层层扩展,直到扩展到终点为止,所以数据量很少时不适合Dijkstra算法。处理该算法时,要特别注意在由一个点找到相邻该点最近点的时候,记得要将相邻的点的距离更新。

  Dijkstra一般的表述通常有两种方式,一种用永久和临时标号方式,一种是用OPEN, CLOSE表的方式,这里是采用第二种方式,也就是采用的贪心法的算法策略,大概过程如下:
  1.定义两个集合:open和close,open用于存储未遍历的节点,close用来存储已遍历的节点;
  2.初始阶段,将初始节点放入close,其他所有节点放入open;
  3.以初始节点为中心向外一层层遍历,获取离指定节点最近的子节点放入close并重新更新相邻点的距离,直至close包含所有子节点;

  此方法由一个点遍历了其他所有点,所以可以知道该点到其他所有点的距离,时间复杂度很高。那个demo是一个一个数据初始化的,我将它改为用数组存储,然后用for循环来初始化,也就是将它封装成我需要的数据接口,并没有很大的优化。

  算法核心只有两个函数:

/**
* 获取与node最近的子节点
*/
private Node getShortestPath(Node node) {
Node res = null;
int minDis = Integer.MAX_VALUE;
Map<Node, Integer> childs = node.getChild(); // 循环比较,找出离node最近的子节点
for (Node child : childs.keySet()) {
if (open.contains(child)) {
int distance = childs.get(child);
if (distance < minDis) {
minDis = distance;
res = child;
}
}
}
return res;
}
public void computePath(Node start) {
Node nearest = getShortestPath(start);// 取距离start节点最近的子节点,放入close
if (nearest == null) {
return;
}
close.add(nearest);
open.remove(nearest);
Map<Node, Integer> childs = nearest.getChild();
for (Node child : childs.keySet()) {
if (open.contains(child)) {// 如果子节点在open中
Integer newCompute = path.get(nearest.getName()) + childs.get(child);
if (path.get(child.getName()) > newCompute) {// 之前设置的距离大于新计算出来的距离
path.put(child.getName(), newCompute); start.getChild().put(child, newCompute);
close.add(start); pathInfo.put(child.getName(), pathInfo.get(nearest.getName()) + "-" + child.getName());
}
}
}
computePath(start);// 重复执行自己,确保所有子节点被遍历
computePath(nearest);// 向外一层层递归,直至所有顶点被遍历
}

  那个demo漏了两行代码,就是找到最近的路径后,没有更新相邻点的距离

  start.getChild().put(child, newCompute);
  close.add(start);

  这是一个Android平板的应用,代码在:http://pan.baidu.com/share/link?shareid=3275093017&uk=3726801344

  还有很多东西没优化,欢迎指出,一起学习!

Java用Dijkstra算法实现地图两点的最短路径查询(Android版)的更多相关文章

  1. [算法] Dijkstra算法(带权有向图 最短路径算法)

    一.带权有向图 二.算法原理 1)由于我们的节点是从1-6,所以我们创建的列表或数组都是n+1的长度,index=0的部分不使用,循环范围为1-6(方便计算). 2)循环之前,我们先初始化dis数组和 ...

  2. java 蓝桥杯算法提高 _1区间k大数查询

    import java.util.Scanner; public class _1区间K大数查询 { public static void main(String[] args) { Scanner ...

  3. Java实现Dijkstra算法求最短路径

    任务描述:在一个无向图中,获取起始节点到所有其他节点的最短路径描述 Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层 ...

  4. JAVA实现DIJKSTRA算法

    import java.util.Queue; import java.util.LinkedList; public class dijkstra{ public static void main( ...

  5. Dijkstra算法:任意两点间的最短路问题 路径还原

    #define _CRT_SECURE_NO_WARNINGS /* 7 10 0 1 5 0 2 2 1 2 4 1 3 2 2 3 6 2 4 10 3 5 1 4 5 3 4 6 5 5 6 9 ...

  6. hdu 2544 最短路(两点间最短路径)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2544 方法一:dijkstra算法,求两点之间最短路径. /*********************** ...

  7. Dijkstra算法求最短路径(java)(转)

    原文链接:Dijkstra算法求最短路径(java) 任务描述:在一个无向图中,获取起始节点到所有其他节点的最短路径描述 Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到 ...

  8. 数据结构与算法系列研究七——图、prim算法、dijkstra算法

    图.prim算法.dijkstra算法 1. 图的定义 图(Graph)可以简单表示为G=<V, E>,其中V称为顶点(vertex)集合,E称为边(edge)集合.图论中的图(graph ...

  9. 求最短路径(Bellman-Ford算法与Dijkstra算法)

    前言 Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的.这时候,就需要使用其他的算法来求 ...

随机推荐

  1. redBag

    var redBag = (function () { var initialed = false, raining = true, createInterval, walkInterval, cre ...

  2. PHP中将对数据库的操作,封装成一个工具类以及学会使用面向对象的方式进行编程

    <?php class SqlTool { //属性 private $conn; private $host="localhost"; private $user=&quo ...

  3. struts2笔记11-OGNL

    1.OGNL Object-Graph Navigation Language,对象-图 导航语言,可以方便的操作struts2值栈对象 2.对象栈操作方法 (1)action普通属性的访问方法 &l ...

  4. 用python实现文件读取和内容替换

    infile = open("D:/test.txt", "r") #打开文件 outfile = open("D:/pp2.txt", & ...

  5. intial-scale=1的含义

    meta name="viewport" content="width=device-width,initial-scale=1.0" 解释  <meta ...

  6. RDLC报表 在WinForm里运行出现 未能加载文件或程序集 Microsoft.ReportViewer.WinForms, Version=11.0.0.0 System.IO.FileNotFoundException

    原文:RDLC报表 在WinForm里运行出现 未能加载文件或程序集microsoft.reportviewer.winforms 推荐以下方案二 做一下记录顺便帮助一下遇到问题的朋友. 做RDLC报 ...

  7. IRC配置for open source community

    IRC是开源社区进行交流使用的一个很重要的工具. 但是很多公司有限制,不让在办公电脑上, 安装IRC的客户端. ZNC + weechat 是一个可以替代的 选择. irccloude 也是一个可替代 ...

  8. Cannot retrieve metalink for repository: epel.

    Error: Cannot retrieve metalink for repository: epel. Please verify its path and                     ...

  9. iOS中通知传值

    NSNotification 通知中心传值,可以跨越多个页面传值, 一般也是从后面的页面传给前面的页面.   思路: 第三个界面的值传给第一个界面. 1. 在第一个界面建立一个通知中心, 通过通知中心 ...

  10. C#反射概念以及实例详解【转】

    2009-08-28 13:12 佚名 互联网 我要评论(1) 字号:T | T C#反射概念以及实例向你介绍了C#反射的基本内容以及C#反射实例的简单应用,希望对你了解和学习C#反射以及C#反射实例 ...