文章目录

  • 1. 算法解析
    • 1.1 建模
    • 1.2 最短路径算法Dijkstra
    • 1.3 时间复杂度
    • 1.4 工程实践
  • 2. 总结引申

问题:地图软件的最优路线是如何计算出来的吗?底层依赖了什么算法呢?

1. 算法解析

1.1 建模

把每个岔路口看作一个顶点,岔路口与岔路口之间的路看作一条边,路的长度就是边的权重。如果路是单行道,就在两个顶点之间画一条有向边;如果路是双行道,就在两个顶点之间画两条方向不同的边。这样,整个地图就被抽象成一个有向有权图

代码表达:

public class Graph { // 有向有权图的邻接表表示private LinkedList<Edge> adj[]; // 邻接表private int v; // 顶点个数public Graph(int v) {this.v = v;this.adj = new LinkedList[v];for (int i = 0; i < v; ++i) {this.adj[i] = new LinkedList<>();}}public void addEdge(int s, int t, int w) { // 添加一条边this.adj[s].add(new Edge(s, t, w));}private class Edge {public int sid; // 边的起始顶点编号public int tid; // 边的终止顶点编号public int w; // 权重public Edge(int sid, int tid, int w) {this.sid = sid;this.tid = tid;this.w = w;}}// 下面这个类是为了dijkstra实现用的private class Vertex implements Comparable<Vertex> {public int id; // 顶点编号IDpublic int dist; // 从起始顶点到这个顶点的距离public Vertex(int id, int dist) {this.id = id;this.dist = dist;}@Overridepublic int compareTo(Vertex o) { // 按照dist从小到大排序if (o.dist > this.dist) return -1;else return 1;}}
}

1.2 最短路径算法Dijkstra

public void dijkstra(int s, int t) { // 从顶点s到顶点t的最短路径int[] predecessor = new int[this.v]; // 用来还原最短路径Vertex[] vertexes = new Vertex[this.v]; // 记录起始顶点到这个顶点的距离for (int i = 0; i < v; ++i) { // 初始化dist为无穷大vertexes[i] = new Vertex(i, Integer.MAX_VALUE);}PriorityQueue<Vertex> heap = new PriorityQueue<>(); // 小顶堆boolean[] inQueue = new boolean[this.v]; // 标记是否进入过队列heap.add(vertexes[s]); // 先把起始顶点放到队列中vertexes[s].dist = 0;inqueue[s] = true;while (!heap.isEmpty()) {Vertex minVertex= heap.poll(); // 取dist最小的顶点if (minVertex.id == t) break; // 最短路径产生了for (int i = 0; i < adj[minVertex.id].size(); ++i) {Edge e = adj[minVertex.id].get(i); // 取出一条minVetex相连的边Vertex nextVertex = vertexes[e.tid]; // minVertex-->nextVertex//找到一条到nextVertex更短的路径if (minVertex.dist + e.w < nextVertex.dist) {nextVertex.dist = minVertex.dist + e.w; // 更新distpredecessor[nextVertex.id] = minVertex.id; //更新前驱顶点if (inqueue[nextVertex.id] == false) { // 如果没有在队列中heap.add(nextVertex); // 就把它放到队列中inqueue[nextVertex.id] = true;}}}}// 输出最短路径System.out.print(s);print(s, t, predecessor);
}private void print(int s, int t, int[] predecessor) {if (s == t) return;print(s, predecessor[t], predecessor);System.out.print("->" + t);
}

1.3 时间复杂度

在刚刚的代码实现中,最复杂就是while循环嵌套for循环那部分代码了。while循环最多会执行V次(V表示顶点的个数),而内部的for循环的执行次数不确定,跟每个顶点的相邻边的个数有关,我们分别记作E0,E1,E2,……,E(V-1)。如果我们把这V个顶点的边都加起来,最大也不会超过图中所有边的个数E(E表示边的个数)。

for循环内部的代码涉及从优先级队列取数据、往优先级队列中添加数据、更新优先级队列中的数据,这样三个主要的操作。我们知道,优先级队列是用堆来实现的,堆中的这几个操作,时间复杂度都是O(logV)(堆中的元素个数不会超过顶点的个数V)。

所以,综合这两部分,再利用乘法原则,整个代码的时间复杂度就是O(E*logV)。

1.4 工程实践

做工程不像做理论,一定要给出个最优解。理论上算法再好,如果执行效率太低,也无法应用到实际的工程中。对于软件开发工程师来说,我们经常要根据问题的实际背景,对解决方案权衡取舍。类似出行路线这种工程上的问题,我们没有必要非得求出个绝对最优解。很多时候,为了兼顾执行效率,我们只需要计算出一个可行的次优解就可以了。

  • 虽然地图很大,但最短路径或者说较好的出行路径,并不会很“发散“,在地图上画个小区块,恰好覆盖两个点,执行Dijkstra算法,提高效率。
  • 如果两点距离很远,比如北京海淀区到上海黄埔区,把北京和上海看作一个点,先规划大的路线,再细化到每个阶段的小路线。

2. 总结引申


44.讲最短路径:地图软件是如何计算出最优出行路径的相关推荐

  1. 最短路径:地图软件是如何计算出最优出行路径的?

    ------ 本文是学习算法的笔记,<数据结构与算法之美>,极客时间的课程 ------ 今天,从地图软件的路径规划问题讲起,带你看看常用的最短路径算法(Shortest Path Alg ...

  2. 【最短路径】:地图软件是如何计算出最优出行路径的?

    基础篇的时候,我们学习了图的两种搜索算法,深度优先搜索和广度优先搜索.这两种算法主要是针对无权图的搜索算法.针对有权图,也就是图中的每条边都有一个权重,我们该如何计算两点之间的最短路径(经过的边的权重 ...

  3. 高德地图绘制标记点,点击弹出弹框进入第三方地图软件

    需求:根据经纬度绘制标记点,点击标记点弹出弹框和底部按钮,点击顶部弹框进入二级界面,点击底部按钮弹出第三方地图软件选择页,实现跨进程跳转. 效果图: 项目是公司项目,只放出重要部分代码. final ...

  4. 手机导航软件和地图软件的易用性思考

    写这篇文字是由某大虾谈及Ophone屏蔽Google Map引起,文中谈到了Google Map和高德地图,讲到打开和放大地图速度,讲到定位和搜索速度,讲到导航和LBS,大部分观点我认同,但说Goog ...

  5. 删除加减 高德地图_网上叫个车就这么简单!活用手机地图软件其实不难|银发智慧学堂...

    现在出行实在是太方便了. 出门前就在网上约个车,到了小区门口,没一会儿,叫的车就来了. 可是,对于老年人来说,他们还是普遍习惯在路边挥手招车.有时侯,遇着上下班高峰期,这车实在是不好叫啊. 今天,咱们 ...

  6. linux安卓导航软件下载,五款安卓导航(地图)软件耗电量评测

    智能手机的普及丰富了我们的碎片时间,但是没电的苦恼却困扰着几乎所有的智能手机用户."用android手机一定是好男人,因为晚上都要回家充电."这个段子绝对不是空穴来风,如果你手头正 ...

  7. 美国在线地图软件测评:谷歌居首必应次之

    在线地图服务成为多数网民每天必用的软件(腾讯科技配图) 腾讯科技讯(马乔)北京时间10月6日消息,根据国外媒体报道,目前在线地图服务软件已列在电子邮件和谷歌之后,成为多数网民每天必用的软件.谷歌地图. ...

  8. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第44讲:PHP程序设计中的COOKIE

    陈力:传智播客古代 珍宝币 泡泡龙游戏开发第44讲:PHP程序设计中的COOKIE 服务器在客户端保存用户的信息,就要用到cookie.Cookie在客户机(浏览器)就是一个字符串,可以通过setco ...

  9. uni-app打开第三方地图软件进行导航

    最近在开发字节小程序的过程中遇到地图导航的需求,相信大家也会遇到所以我为大家整理了一篇干货内容. 下面是我整理的代码案例---------记得喝水(太"干"了,复制就能用). 效果 ...

最新文章

  1. 今天已经算一下过来有一个礼拜了,还是感觉是在熬日子似的
  2. rand(),repmat(),logical()函数的使用
  3. android 后台耗时,android教程之使用asynctask在后台运行耗时任务
  4. 雷林鹏分享:MySQL ALTER命令
  5. Ubuntu下华为方舟编译器环境安装
  6. UNIX 时间戳 C#
  7. python学习笔记10-匿名函数lambda
  8. 七人表决器VHDL代码
  9. 高职高专院校人才培养工作水平评估工作感想
  10. shell 脚本中常用的列表
  11. USB协议详解第29讲(USB设备状态及数据交互条件)
  12. 国培 计算机远程培训心得,国培远程培训感言3篇
  13. Android使用串口打印机打印图片方法
  14. 预后建模绕不开的lasso cox回归
  15. 给定数字0-9各若干个。你可以以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小(注意0不能做首位)
  16. 毒舌电影 是怎么成长起来的?为什么这么快就被封了
  17. 如何安装windows操作系统?(win10、Window11、win7、win8)
  18. 二本计算机类专业农村学生出路,农村“二本”大学生有哪些出路?主要出路有四条,第2条可逆袭...
  19. Webdings,Wingdings图形字体对照表
  20. 企业如何选择一款适合自己的信息化管理系统?

热门文章

  1. SQL表连接的几种方式
  2. 流式处理 术语解释 Exactly-once与Effectively-once
  3. getrawinputdata鼠标_获取鼠标的原始移动值
  4. Python常用类型转换函数
  5. 20171024 三季报业绩上涨个股一览
  6. java多态性练习题---主人和狗狗玩接飞盘游戏,狗狗健康值减少10,与主人亲密度增加5 主人和企鹅玩游泳游戏,企鹅健康值减少10,与主人亲密度增加5
  7. HSM硬件加密机国密标准解读
  8. python设置文件名长度对齐
  9. zookeeper 进入客户端_ZooKeeper:第三方客户端 ZKClient
  10. 编写一个方法,将数组传入进去之后将数组中的元素反转