疫情原因,公司干脆利落地把我们业务组给裁啦,我也光荣地成为了一个下岗待业的老程序员。

开发工作不好找啊,毕竟都要35岁以下的,所以我寻思再就业可以换个方向,比如说送外卖,再怎么说X团、X了么也是大厂嘛~

既然下定决心,第一步就是要武装头脑,拿起理论的武器,送外卖第一要务是什么?快!!天下武功,唯快不破。速度速度速度,重要的事情说三遍。

如何快速抵达商家,再快速将饭菜送到顾客手中,少跑路是关键——这就是最短路径问题,下面我就描述一下,我是如何使用Dijkstra算法结合回龙观的地图来计算最短路径的。

选回龙观的原因:1、回龙观的道路情况很好,基本上是横平竖直;2、我家就在这,送外卖在家附近送,路熟。


回龙观的地图如上,因为是做实验,就选取了部分区域:北起回南北路,南至同成街;东起G6辅路,西至文化东路。

之前我的两篇描述最短路径算法的文章中,使用的图都是类似:

如果用在地图上,就有些不合适,因为不太好体现真实情况,如下图:

在示意图中,两点之间只会有一条边A,但现实中,两地的路线有B、C两条,所以为了让示意图更贴合显示,就有了变种图:

每一个方块代表一个顶点,两个相邻顶点的边权重视为1.

如上图,其中蓝色数字的方块代表可通过的路,红色英文的方块代表不可通行,其顶点边权组合应如下:

1-2-1,1-16-1

2-1-1,2-3-1

3-2-1,3-4-1,3-17-1

4-3-1,4-5-1

5-4-1,5-6-1

...... ......

18-17-1,18-19-1,18-20-1,18-21-1

假如以北店嘉园北区东门为起点,即19,以龙回苑西门为终点,即5.

可得最短路线为19-18-21-7-6-5或19-18-17-3-4-5,再结合实际道路情况,例如拥堵程度、红绿灯、单行路等,可得出相对较短的路线。

假设龙禧二街常年堵车,边权设为2,则较短路径应为第二条。

我使用地图的测距工具得到了 以下不怎么精确的距离:

以路口为点,两点之间的距离如上图,单位公里。

我假设每一个方块都代表100*100米,那么示意图如下:

不要问为什么是圆而不是说好的方块,因为圆比方块好画~~~

也请忽视圆的大小不一,单位固定都是100*100米。

接着我们上代码。

首先我们必须构建顶点的边权数据,类似1-45-1,1-74-1这种。

在这里我采用了Guava里的HashBasedTable结构,即Key1-Key2:Value。

Table<Integer, Integer, Integer> ppw = HashBasedTable.create();ppw.put(1, 45, 1);ppw.put(1, 74, 1);ppw.put(45, 1, 1);ppw.put(74, 1, 1);

在本图里,共有296个顶点,相关边更多,纯手工录入会崩溃的,所以我写了程序,根据输入的顶点范围生成相应的代码。即便这样也是很累人的。

接着实现Dijkstra算法。伪代码如下,入参有两个:起点,终点,

public void getShortestPath(Integer start, Integer end){ 1、构建到某一顶点最短路径的起点Map——parentMap 2、构建已处理最短路径顶点Map——s;构建待处理最短路径顶点Map——w 3、构建(顶点A-顶点B:边权)的Table——ppw 4、遍历所有顶点{  4.1将w转为优先队列,并取出最小值的顶点,将其从w挪入s,并以此为顶点(设为Key1)计算其相邻顶点的权重。  4.2如果取出的最小值顶点就是终点,且最小值不是无穷大(在程序中用Integer.MAX_VALUE代替),说明已经计算到终点,不需要计算后面的点,直接跳出循环。  4.3内循环遍历所有顶点(设为Key2),根据Key1-Key2从ppw中取出权重。  4.4如果ppw取出为null,说明两顶点间无路径。  4.5根据Key1、Key2的值、边权对Key2进行松弛操作。 }}

至此,核心代码已经完成,后续还有输入骑手、商家、顾客,调用核心代码,并输出路径的方法等,在此不再赘述。

以下为测试结果。

假设骑手在回龙观西大街与育知东路的交叉口(即24),商家在北京华联同成街店(即177),顾客在天露园二区北门(即89),计算的结果如下:

以商家到顾客路线为例,地图给出的路径如图:

程序给出的路径:

基本还算一致。

当然这只是一个很简陋的程序,有许多实际问题没有考虑,比如出行方式、拥堵、红绿灯、单行道、禁行路段、立体交通等。

例如点26,同成街与育知东路交叉点,这其实是个桥,如果从175到236,开车的话是不可能走175-26-236路线的,必须绕一圈。

这篇文章其实也只是记录一下个人将理论与实际相结合的学习过程,疏漏错误在所难免。

好了,不说了,仅有理论的指导还是不够的,我去升级装备了。

©著作权归作者所有:来自51CTO博客作者mb5fe559d8b9ae4的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. Android Studio开启虚拟机报错!emulator: ERROR: x86 emulation c
  2. Linux入门基础知识(1)-------Linux基础概念
  3. Android Studio 批量打包(渠道包,最新基于Gradle 2.2.1、Android
  4. 再一次在Eclipse下配置Android
  5. 详解Android增量更新
  6. Android实现多渠道打包,动态替换包名、Icon、图片等资源,解决因app
  7. Android 图形:绘制渐变色奥运五环图形,游戏文字,验证码,Matrix旋转,缩
  8. Android 自定义View 仿蚂蚁信用分析(正多边形)
  9. Android OpenGL ES 基础:绘制三角形

随机推荐

  1. Linux下Android(安卓)ADB驱动安装详解
  2. JNI 入门
  3. 8. android Tab 选项卡控件
  4. Android Service AIDL 远程调用服务 【简
  5. Android Debug certificate expired
  6. android实现服务器图片本地缓存
  7. Android EditText 光标控制,颜色修改,显示
  8. 利用 Android Keystore 系统 加密存储和
  9. Android笔记1
  10. Android TextView全属性