前言

最近由于换了工作,期间也有反思和总结上家公司的得失,总觉得有什么事情当初可以完成或者完成得更好,其中TSP问题就是其中之一。当初在开发一个仓配系统的时候,有一个线路排程的需求,当时自己简单在纸上画了思路,发现求精确解算法复杂度是N!,所以去百度,发现了NPC问题的概念,但是一直以来都没有对这个问题好好研究过,最终只是选择了贪心算法这一求近似解的方案,正好这是我的第一篇博客,就拿这个“遗憾”开刀吧。

1、  利用百度地图API模拟TSP的各个城市点

1.1、 调用百度地图API解析经纬度

这里首先到百度地图API官网申请一个apiKey,调地址解析接口会使用到,其中地址解析接口的参数可以访问http://lbsyun.baidu.com/index.php?title=uri/api/web开查看,这里我先将它截图:

将示例中的url(这里的output我采用json)在浏览器中输入,会得到如下结果:

这里利用HttpRequest方法来调用地址解析接口,类似于爬虫,最后将结果反序列化为实体类,代码如下:

///地址解析结果的实体类


///利用HttRequest调用API接口

1.2、利用经纬度计算两个地址间的距离

其实这个网上有大量雷同的计算方法,但是这个方法是我很久以前引用过来的,原出处已经翻不到了,只好在这里点出此算法非我原创,若有幸让原作者看到,请通知我注明出处。这里我先简单的介绍一下算法思路,以地球的球心作为坐标系原点作一个三维坐标系,如图:

其中坐标A(x1,y1,z1),坐标B(x2,y2,z2),注意一下,其中x=r*sinɵ*cosɸ,y=r* r*sinɵ*sinɸ,z=r*cos ɵ,这里将角度转化为π来计算,让经纬度*π/180,那么坐标点在北纬时:ɵ=π/2-纬度*π/180;坐标点在南纬时:ɵ=π/2+纬度*π/180;坐标点在西经时:ɸ=π*2-经度*π/180;这个换算完成后,就可以通过给(x1-x2)^2+(y1-y2)^2+(z1-z2)^2开方计算出两点间的直线距离d,然后通过余弦定理求两点之间的夹角,最后计算出两点之间的球面距离,代码如下:

2、  通过群蚁算法求最短路径的近似解

关于群蚁算法,网上的介绍也有很多,不过偷下懒,只关注了C#的实现,这里参考的是园子里数据之巅的群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法 ,我就指出我对这篇文章理解起来比较费力的几点吧。

(1)这里的轮盘赌注法是遗传算法的一种思路,即通过产生一个随机数来选择下一个访问的城市,可以把0.081、0.74、0.18视为[0,0.081],[0.081,0.821],[0.821,1]这么三个区间,然后产生一个0到1的随机数(保留两位有效小数),当这个随机小数属于区间[0,0.081]时,选择城市B,属于[0.081,0.821]时,选择城市C,属于[0.821,1]时,选择城市D。这里是对群蚁算法的一种优化,优化方式有多种,可以自行查阅资料。

(2)代码处关于List的深复制

这个原作者没有给出实现,我用拓展方法实现了一下,代码如下:

(3)贪心算法的实现

这个原作者也没有给出,于是我自己实现了一下(可能在时间和空间复杂调用上有很大缺陷,这个的优化工作本人暂不处理,大家有兴趣的可以自己实现),代码如下:

整个群蚁算法的代码基本沿用了原作者的代码,没有什么改变,所以就不贴整套的了。

3、 测试代码:

运行结果:

这里注意调整BaseTspAntSystem类构造方法的参数,信息素越强(参数a),即能见度越高,收敛性越强,得到的结果路径就越单一,精确性会差一些,大家可以自己调整下参数观察不同的结果。

4、 总结

这里基本上是在收集别人的代码和成果来解决自己的问题,文章引用的大部分也都是别人的代码,但重点是,一定要自己一点点的理解和尝试。

参考资料:

【1】新浪博客,吴超,根据两点经纬度计算距离【转】

【2】博客园,数据之巅,群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法

【3】网易博客,蚁群优化算法ACO ;

【4】博客园,柠檬雨,Evolutionary Computing: 遗传算法_轮盘赌选择(转载)

【5】博客园,Learning hard, [C#进阶系列]专题一:深入解析深拷贝和浅拷贝

利用百度地图API和群蚁算法,对TSP问题进行模拟与求解的更多相关文章

  1. 利用百度地图API,获取经纬度坐标

    利用百度地图API,获取经纬度坐标 代码很简单,但在网上没找到现成的获取地图经纬度的页面. 就是想,给当前页面传递一个经纬度,自动定位到此经纬度.然后可以重新选择,选择完返回经纬度. 效果如下: 源代 ...

  2. 利用百度地图API,在浏览器中找到自己的位置

    首先你得有个百度地图的秘钥,http://lbsyun.baidu.com/apiconsole/key 剩下的就是编码了 这里面会用到一个javascript里的一个函数,getMyLocation ...

  3. 利用百度地图api实现定位

    使用百度地图api前需要先获取一个百度地图开放平台的访问应用AK, 获取百度地图开放平台访问应用AK方式:注册百度账号-->申请百度开发者-->获取密匙-->使用相关功能. 注册账号 ...

  4. 【百度地图API】如何利用地图API制作汽车沿道路行驶的动画?——如何获得道路层数据

    原文:[百度地图API]如何利用地图API制作汽车沿道路行驶的动画?--如何获得道路层数据 有几个做汽车导航的朋友问我说,他们想在地图上制作一辆车沿着道路行驶的动画.可是,百度地图的道路数据并没有公开 ...

  5. 【百度地图API】建立全国银行位置查询系统(四)——如何利用百度地图的数据生成自己的标注

    原文:[百度地图API]建立全国银行位置查询系统(四)--如何利用百度地图的数据生成自己的标注 摘要: 上一章留个悬念,"如果自己没有地理坐标的数据库,应该怎样制作银行的分布地图呢?&quo ...

  6. 【百度地图API】JS版本的常见问题

    1.请问如何将我的店铺标注在百度地图上?我是否可以做区域代理?在百度地图上标注是否免费? 答复: 这里只负责API的技术咨询,不解决任何地图标注问题.在百度地图上标注自己公司,即气泡标注业务.该业务已 ...

  7. 【百度地图API】如何制作自定义样式的公交导航结果面板?

    原文:[百度地图API]如何制作自定义样式的公交导航结果面板? 摘要: 百度地图API有默认的公交导航结果面板,但样式比较单一:而百度地图上的结果面板就比较美观.如何利用百度地图API来制作一个比较美 ...

  8. 【百度地图API】如何在地图上添加标注?——另有:坐标拾取工具+打车费用接口介绍

    原文:[百度地图API]如何在地图上添加标注?--另有:坐标拾取工具+打车费用接口介绍 摘要: 在这篇文章中,你将学会,如何利用百度地图API进行标注.如何使用API新增的打车费用接口. ------ ...

  9. 【百度地图API】建立全国银行位置查询系统(一)——如何创建地图

    原文:[百度地图API]建立全国银行位置查询系统(一)--如何创建地图 <摘要>你将在第一章中学会以下知识: 如何创建一个网页文件 怎样利用百度地图API建立一张2D地图,以及3D地图 如 ...

随机推荐

  1. jQuery下的轮播

    以前用js做过轮播 今天用JQ插件是最基本的 在官网可以下 布局:<body><div id="div1"> <ul id="lunbo&q ...

  2. iOS 类微信语音播放之切换听筒和扬声器的方法解决方案

    [[UIDevice currentDevice] setProximityMonitoringEnabled:NO];   //建议在播放之前设置yes,播放结束设置NO,这个功能是 //添加监听 ...

  3. 如何定位死循环或高CPU使用率(linux)

    如何定位死循环或高CPU使用率(linux)  确定是CPU过高 使用top观察是否存在CPU使用率过高现象 找出线程 对CPU使用率过高的进程的所有线程进行排序 ps H -e -o pid,tid ...

  4. 未找到与约束ContractName Microsoft.VisualStudio.Text.ITextDocumentFactoryService... 匹配的导出 VS2012报错

    刚安装完VS2012,打开VS2012新建项目,但是并没有像之前那样顺利的创建页面,而是弹出了一个错误窗口. 我的系统是win7旗舰版 64位 ,同时安装了VS2010和VS2012.然后我又试了一下 ...

  5. ASP.NET配置Ueditor编辑器上传图片路径

    1.配置ueditor/editor_config.js文件,将 //图片上传配置区 ,imageUrl:URL+"net/imageUp.ashx" //图片上传提交地址 ,im ...

  6. Java集合中Map接口的使用方法

    Map接口 Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够实现根据key快速查找value: Map中的键值对以Entry类型的对象实例形式存在: 建(key值 ...

  7. 【linux环境下】RabbitMq的安装和监控插件安装

    [注意安装过程中,提示某些命令not found,直接yum isntall一下就好了] 以下是我在CentOS release 6.4下亲测成功的. RabbitMq的安装:   RabbitMQ是 ...

  8. mysql bin log日志

    装mysql,运行一段时间后,在mysql目录下出现一堆类似mysql-bin.000***,从mysql-bin.000001开始一直排列下来,而且占用了大量硬盘空间,高达几十个G. 对于这些超大空 ...

  9. EasyUI--messager

    1. alert 方法 <script type="text/javascript"> $( function() { $.messager.alert("调 ...

  10. ackerman递归

    定义: n+1        n=0 A(m,n)={A(m-1,1) m=0 A(m-1,A(m,n-1)) n>0,m>0 #include <iostream> #inc ...