Java用Dijkstra算法实现地图两点的最短路径查询(Android版)
地图上实现最短路径的查询,据我了解的,一般用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版)的更多相关文章
- [算法] Dijkstra算法(带权有向图 最短路径算法)
一.带权有向图 二.算法原理 1)由于我们的节点是从1-6,所以我们创建的列表或数组都是n+1的长度,index=0的部分不使用,循环范围为1-6(方便计算). 2)循环之前,我们先初始化dis数组和 ...
- java 蓝桥杯算法提高 _1区间k大数查询
import java.util.Scanner; public class _1区间K大数查询 { public static void main(String[] args) { Scanner ...
- Java实现Dijkstra算法求最短路径
任务描述:在一个无向图中,获取起始节点到所有其他节点的最短路径描述 Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层 ...
- JAVA实现DIJKSTRA算法
import java.util.Queue; import java.util.LinkedList; public class dijkstra{ public static void main( ...
- 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 ...
- hdu 2544 最短路(两点间最短路径)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2544 方法一:dijkstra算法,求两点之间最短路径. /*********************** ...
- Dijkstra算法求最短路径(java)(转)
原文链接:Dijkstra算法求最短路径(java) 任务描述:在一个无向图中,获取起始节点到所有其他节点的最短路径描述 Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到 ...
- 数据结构与算法系列研究七——图、prim算法、dijkstra算法
图.prim算法.dijkstra算法 1. 图的定义 图(Graph)可以简单表示为G=<V, E>,其中V称为顶点(vertex)集合,E称为边(edge)集合.图论中的图(graph ...
- 求最短路径(Bellman-Ford算法与Dijkstra算法)
前言 Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的.这时候,就需要使用其他的算法来求 ...
随机推荐
- 【学习笔记03】Javascript数组学习
数组定义的方法一: var Myarr=new Array(); //先声明一维 for(var i=0;i<2;i++){ //一维长度2 Myarr[i]=new Array(); //再声 ...
- check单选框多个全选与取消全选
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- 用python开发简单ftp程序
根据alex老师视频开发的简单ftp程序,只能实现简单的get功能 ftp客户端程序: #!/usr/bin/env python #_*_ coding:utf-8 _*_ import socke ...
- 2-4. BCD解密(10)
BCD数是用一个字节来表达两位十进制的数,每四个比特表示一位.所以如果一个BCD数的十六进制是0x12,它表达的就是十进制的12.但是小明没学过BCD,把所有的BCD数都当作二进制数转换成十进制输出了 ...
- CSS自学笔记(10):CSS3盒子模型
CSS3为CSS技术的升级版本.最新版本. 就CSS而言,它是一个模块,是一个庞大而又复杂的模块,但是在CSS3中,将这一个庞大的模块分解为一个个容易理解的同时又很精简的小模块,同时CSS3中又添加了 ...
- HibernateTransactionManager 和 hibernateTemplate的区别
在applicationContext.xml中有如下配置: <bean id="hibernateTemplate" class="org.springframe ...
- 14.2.3 InnoDB Redo Log
14.2.3 InnoDB Redo Log 14.2.3.1 Group Commit for Redo Log Flushing redo log 是一个基于磁盘数据结构的用于在crash 恢复正 ...
- DML
DML(Data Manipulation Language 数据操控语言),使用insert.update.delete进行数据库的操作.DML一:插入语句 标准的插入语句 insert into ...
- html系列教程--ol ul li
<li> 标签:配合ol,ul实现有序,无序列表以及导航实现. demo: <ol> <li>Coffee</li> <li>T ...
- iOS - SQLite Database 操作数据库
iOS - SQLite Database 操作数据库 Sqlite 能被用在ios上做数据处理用,只要你懂得一点sql 就很容易使用sqlite 1:创建一个简单的View based appl ...