问题:项目开发遇到了一个行程规划问题,就是去一个城市几个地点拜访,要求串联的距离最短

思考:这是一个旅行商的问题,不过这个不需要回到起点,只要求到终点就完成拜访,于是百度了很久,最终采用蚁群算法。

介绍:用蚂蚁的行走路径表示待优化问题的可行解,整个蚂蚁群体的所有路径构成待优化问题的解空间。路径较短的蚂蚁释放的信息素量较多,随着时间的推进,较短的路径上累积的信息素浓度逐渐增高,选择该路径的蚂蚁个数也愈来愈多。最终,整个蚂蚁会在正反馈的作用下集中到最佳的路径上,此时对应的便是待优化问题的最优解。

思路:

1.设定一个起点,其他的都是需要拜访的点,所有点设为一个数组,循环设置每个点为起点,调用高德api获取这个点与其他各点之间的距离,自身点设为无穷大,获取到的是一个二维数组,为了性能,调用的是高德api的批量接口,防止频繁请求接口。

2.得到的二维数组既是一个点与各个点之间的距离,通过模拟蚁群算法,得到最优解

蚁群算法代码:

蚁群算法中主要有下面几个参数需要设定:

蚂蚁数量: 
设M表示城市数量,m表示蚂蚁数量。m的数量很重要,因为m过大时,会导致搜索过的路径上信息素变化趋于平均,这样就不好找出好的路径了;m过小时,易使未被搜索到的路径信息素减小到0,这样可能会出现早熟,没找到全局最优解。一般上,在时间等资源条件紧迫的情况下,蚂蚁数设定为城市数的1.5倍较稳妥。

信息素因子: 
信息素因子反映了蚂蚁在移动过程中所积累的信息量在指导蚁群搜索中的相对重要程度,其值过大,蚂蚁选择以前走过的路径概率大,搜索随机性减弱;值过小,等同于贪婪算法,使搜索过早陷入局部最优。实验发现,信息素因子选择[1,4]区间,性能较好。

启发函数因子: 
启发函数因子反映了启发式信息在指导蚁群搜索过程中的相对重要程度,其大小反映的是蚁群寻优过程中先验性和确定性因素的作用强度。过大时,虽然收敛速度会加快,但容易陷入局部最优;过小时,容易陷入随机搜索,找不到最优解。实验研究发现,当启发函数因子为[3,4.5]时,综合求解性能较好。

信息素挥发因子: 
信息素挥发因子表示信息素的消失水平,它的大小直接关系到蚁群算法的全局搜索能力和收敛速度。实验发现,当属于[0.2,0.5]时,综合性能较好。

信息素常数: 
这个参数为信息素强度,表示蚂蚁循环一周时释放在路径上的信息素总量,其作用是为了充分利用有向图上的全局信息反馈量,使算法在正反馈机制作用下以合理的演化速度搜索到全局最优解。值越大,蚂蚁在已遍历路径上的信息素积累越快,有助于快速收敛。实验发现,当值属于[10,1000]时,综合性能较好。

最大迭代次数: 
最大迭代次数值过小,可能导致算法还没收敛就已结束;过大则会导致资源浪费。一般最大迭代次数可以取100到500次。一般来讲,建议先取200,然后根据执行程序查看算法收敛的轨迹来修改取值。

蚂蚁类:

public class Ant implements Cloneable {public int[] m_nPath = new int[PublicFun.N_CITY_COUNT];// 蚂蚁走过的路径public double m_dbPathLength;// 蚂蚁走过的路径长度public int[] m_nAllowedCity = new int[PublicFun.N_CITY_COUNT];// 蚂蚁没有去过的城市public int m_nCurCityNo;// 当前所在城市的编号public int m_nMovedCityCount;// 已经去过的城市数量/** 初始化函数,蚂蚁搜索前调用该方法*/public void Init() {for (int i = 0; i < PublicFun.N_CITY_COUNT; i++) {m_nAllowedCity[i] = 1;// 设置全部城市没有去过m_nPath[i] = 0;// 蚂蚁走过的路径全部设置为0}m_dbPathLength = 0.0; // 蚂蚁走过的路径长度设置为0m_nCurCityNo = 0;//选择一个出发点m_nPath[0] = m_nCurCityNo;// 把出发城市保存的路径数组中m_nAllowedCity[m_nCurCityNo] = 0;// 标识出发城市已经去过了m_nMovedCityCount = 1;// 已经去过的城市设置为1;}/** 覆盖Object中的clone()方法 实现对象的复制*/protected Object clone() throws CloneNotSupportedException {return super.clone();}/** 选择下一个城市 返回值为城市编号*/public int ChooseNextCity() {int nSelectedCity = -1;// 返回结果,初始化为-1// 计算当前城市和没去过城市的信息素的总和double dbTotal = 0.0;double[] prob = new double[PublicFun.N_CITY_COUNT];// 用来保存各个城市被选中的概率for (int i = 0; i < PublicFun.N_CITY_COUNT; i++) {if (m_nAllowedCity[i] == 1)// 城市没去过{// 该城市和当前城市的信息素,随着迭代次数增加,城市之间的信息素会随之变化prob[i] = Math.pow(PublicFun.g_Trial[m_nCurCityNo][i], PublicFun.ALPHA)             * Math.pow(1.0 / PublicFun.g_Distance[m_nCurCityNo][i], PublicFun.BETA);dbTotal = dbTotal + prob[i];// 累加信息素} else// 如果城市去过了 则被选中的概率为0;{prob[i] = 0.0;}}// 进行轮盘选择,信息素值大的选中的概率就会大,选择下一个城市double dbTemp = 0.0;if (dbTotal > 0.0)// 如果总的信息素大于0{dbTemp = PublicFun.rnd(0.0, dbTotal);// 取一个随机数for (int i = 0; i < PublicFun.N_CITY_COUNT; i++) {if (m_nAllowedCity[i] == 1)// 城市没有去过{dbTemp = dbTemp - prob[i];// 相当于轮盘if (dbTemp < 0.0)// 轮盘停止转动,记下城市编号,跳出循环{nSelectedCity = i;break;}}}}/** 如果城市间的信息素非常小 ( 小到比double能够表示的最小的数字还要小 ) 那么由于浮点运算的误差原因,上面计算的概率总和可能为0* 会出现经过上述操作,没有城市被选择出来 出现这种情况,就把第一个没去过的城市作为返回结果*/if (nSelectedCity == -1) {for (int i = 0; i < PublicFun.N_CITY_COUNT; i++) {if (m_nAllowedCity[i] == 1)// 城市没有去过{nSelectedCity = i;break;}}}return nSelectedCity;}/** 蚂蚁在城市间移动*/public void Move() {int nCityNo = ChooseNextCity();// 选择下一个城市m_nPath[m_nMovedCityCount] = nCityNo;// 保存蚂蚁走过的路径m_nAllowedCity[nCityNo] = 0;// 把这个城市设置为已经去过了m_nCurCityNo = nCityNo;// 改变当前城市为选择的城市m_nMovedCityCount++;// 已经去过的城市加1}/** 蚂蚁进行一次搜索*/public void Search() {Init();// 蚂蚁搜索前,进行初始化// 如果蚂蚁去过的城市数量小于城市数量,就继续移动while (m_nMovedCityCount < PublicFun.N_CITY_COUNT) {Move();// 移动}// 完成搜索后计算走过的路径长度CalPathLength();}/** 计算蚂蚁走过的路径长度*/public void CalPathLength() {m_dbPathLength = 0.0;// 先把路径长度置0int m = 0;int n = 0;for (int i = 1; i < PublicFun.N_CITY_COUNT; i++) {m = m_nPath[i];n = m_nPath[i - 1];m_dbPathLength = m_dbPathLength + PublicFun.g_Distance[m][n];}m_dbPathLength = (Math.round(m_dbPathLength * 100)) / 100.0;}}

常量类:

public class PublicFun {public static final double ALPHA = 2.0;//信息素因子public static final double BETA = 3.0;// 启发函数因子, 城市间距离的重要程度public static final double ROU = 0.5;//信息素挥发因子public static int N_IT_COUNT = 200;// 迭代次数public static int N_CITY_COUNT = 15;// 城市数量public static int N_ANT_COUNT = N_CITY_COUNT*2;// 蚂蚁数量public static final double DBQ = 100.0;// 总信息素public static final double DB_MAX = Math.pow(10, 9);// 一个标志数,用来初始化一个比较大的最优路径// 两两城市间的信息量public static double[][] g_Trial;// 两两城市间的距离public static Double[][] g_Distance;// 返回指定范围内的随机整数public static int rnd(int nLow, int nUpper) {return (int) (Math.random() * (nUpper - nLow) + nLow);}// 返回指定范围内的随机浮点数public static double rnd(double dbLow, double dbUpper) {return Math.random() * (dbUpper - dbLow) + dbLow;}
}

算法核心类:

public class Tsp {//蚂蚁数组  public Ant[] m_antAry=new Ant[PublicFun.N_ANT_COUNT];  public Ant[] m_betterAnts=new Ant[PublicFun.N_IT_COUNT];//定义一组蚂蚁,用来保存每一次搜索中较优结果,不参与搜索  public Ant m_bestAnt;//定义一个蚂蚁变量,用来保存最终最优结果,不参与搜索  /* * 初始化数据 */  public void InitData() throws CloneNotSupportedException  {  //初始化所有蚂蚁  PublicFun.g_Trial=new double[PublicFun.N_CITY_COUNT][PublicFun.N_CITY_COUNT];  m_bestAnt=new Ant();  for (int i = 0; i <PublicFun.N_ANT_COUNT; i++)  {  m_antAry[i]=new Ant();  }  for (int i = 0; i < PublicFun.N_IT_COUNT; i++)  {  m_betterAnts[i]=new Ant();  m_betterAnts[i].m_dbPathLength=PublicFun.DB_MAX;//把较优蚂蚁的路径长度设置为一个很大值  }  //先把最优蚂蚁的路径长度设置为一个很大值  m_bestAnt.m_dbPathLength=PublicFun.DB_MAX;  //初始化信息素  for(int i=0;i<PublicFun.N_CITY_COUNT;i++)  {  for(int j=0;j<PublicFun.N_CITY_COUNT;j++)  {  PublicFun.g_Trial[i][j]=1.0;  }  }  Iterator();//开始迭代  }  /* * 更新环境信息素 */  public void UpdateTrial()  {  //临时数组,保存各只蚂蚁在两两城市间新留下的信息素  double[][] dbTempAry=new double[PublicFun.N_CITY_COUNT][PublicFun.N_CITY_COUNT];  //全部设置为0;  for (int i = 0; i <PublicFun.N_CITY_COUNT; i++)  {  for (int j = 0; j < PublicFun.N_CITY_COUNT; j++)  {  dbTempAry[i][j]=0.0;  }  }  //计算新增加的信息素,保存到临时变量  int m=0;  int n=0;  for(int i=0; i<PublicFun.N_ANT_COUNT;i++)  {  for (int j = 1; j < PublicFun.N_CITY_COUNT; j++)  {  m=m_antAry[i].m_nPath[j];  n=m_antAry[i].m_nPath[j-1];  dbTempAry[n][m]=dbTempAry[n][m]+PublicFun.DBQ/m_antAry[i].m_dbPathLength;  dbTempAry[m][n]=dbTempAry[n][m];  }  //最后城市与开始城市之间的信息素
//            n=m_antAry[i].m_nPath[0];
//            dbTempAry[n][m]=dbTempAry[n][m]+PublicFun.DBQ/m_antAry[i].m_dbPathLength;
//            dbTempAry[m][n]=dbTempAry[n][m];  }  //更新环境信息素  for (int i = 0; i < PublicFun.N_CITY_COUNT; i++)  {  for (int j = 0; j < PublicFun.N_CITY_COUNT; j++)  {  //最新的环境信息素 = 留存的信息素 + 新留下的信息素    PublicFun.g_Trial[i][j]=PublicFun.g_Trial[i][j]*PublicFun.ROU+dbTempAry[i][j];  }  }  }  /* * 迭代 */  public void Iterator() throws CloneNotSupportedException  {  //迭代次数内进行循环  for (int i = 0; i < PublicFun.N_IT_COUNT; i++)  {  //每只蚂蚁搜索一遍  for(int j=0;j<PublicFun.N_ANT_COUNT;j++)  {  m_antAry[j].Search();  }  //保存较优结果  for(int j=0;j<PublicFun.N_ANT_COUNT;j++)  {  if (m_antAry[j].m_dbPathLength < m_betterAnts[i].m_dbPathLength)  {  m_betterAnts[i] = (Ant) m_antAry[j].clone();  }  }  UpdateTrial();  }  //找出最优蚂蚁  for(int k=0;k<PublicFun.N_IT_COUNT;k++)  {  if(m_betterAnts[k].m_dbPathLength<m_bestAnt.m_dbPathLength)  {  m_bestAnt=m_betterAnts[k];  }  }  //  getBetterAnt();//输出每次的较优路径
//      getBestAnt();//输出最佳路径  }  /* * 输出最佳路径到控制台.(暂不使用,但保留) */  public void getBestAnt()  {  System.out.println("最佳路径:");  System.out.println( "路径:"+getAntPath(m_bestAnt)+"长度:"+getAntLength(m_bestAnt));  }  /* * 输出每次的较优路径到控制台.(暂不使用,但保留) */  public void getBetterAnt()  {  System.out.println("每一次的较优路径:");  for (int i = 0; i < m_betterAnts.length; i++)  {  System.out.println("("+i+") 路径:"+getAntPath(m_betterAnts[i])+"长度:"+getAntLength(m_betterAnts[i]));  }  }  /* * 返回蚂蚁经过的路径 */  public String getAntPath(Ant ant)  {  String s="";  for(int i=0;i<ant.m_nPath.length;i++)  {  s+=ant.m_nPath[i]+"-";  }  s+=ant.m_nPath[0];  //蚂蚁最后要回到开始城市  return s;  }  /* * 返回蚂蚁经过的长度 */  public double getAntLength(Ant ant)  {  return ant.m_dbPathLength;  }  }

代码转载:https://blog.csdn.net/wuchuanpeng/article/details/51583829

流程图:

代码git地址: https://gitee.com/gx1314/ant_algorithm.git

基于高德地图的行程规划-蚁群算法相关推荐

  1. 蚁群算法C语言最短路径规划,蚁群算法规划路径

    蚁群算法可以用于路径规划,在本例中,地形矩阵用0表示无障碍物.用1表示有障碍物,机器人从1x1处走到10x10处,使用蚁群算法找最短路径. 步骤如下:初始化参数.地形矩阵.信息素矩阵和启发式因子矩阵. ...

  2. 【 无错版】基于蚁群算法的机器人路径规划matlab程序代码实现

    文章目录 1. 按 2. 介绍 3. matlab实现 3.1. 代码 3.2. 效果 1. 按 网上有发的这个算法的错误版的,不知道发的意义何在,是在误人子弟吗???在此对其行为表示强烈的谴责. 错 ...

  3. 基于MATLAB GUI的蚁群算法路径规划实现电动汽车充电站与换电站协调

    基于MATLAB GUI的蚁群算法路径规划实现电动汽车充电站与换电站协调 摘要: 随着电动汽车的普及和发展,电动汽车充电站与换电站的布局和规划变得尤为重要.本文基于MATLAB GUI平台,结合蚁群算 ...

  4. Python实现VRP常见求解算法——蚁群算法(ACO)

    基于python语言,实现经典蚁群算法(ACO)对车辆路径规划问题(CVRP)进行求解. 目录 优质资源 1. 适用场景 2. 求解效果 3. 问题分析 4. 数据格式 5. 分步实现 6. 完整代码 ...

  5. 【智能优化算法】蚁群算法ACO

    文章目录 [智能优化算法] 蚁群算法 1. 简介 1.1 简介 1.2 蚁群流程图 1.3 分类(可以不看) 2. 算法 2.1 参数讲解 2.2 计算公式 1) 转移概率公式 2) 启发式因子计算公 ...

  6. 路径算法:蚁群算法(ant colony optimization, ACO)

    一, 蚁群算法概述 自然界中有一个神奇的现象,即蚂蚁在没有提示的情况下总是能够找到从巢穴到食物的最短路径,这是为什么呢?原因就是蚂蚁在寻找食物时,能在其走过的路径上释放一种特殊的分泌物--信息素,随着 ...

  7. 【路径规划】基于matlab蚁群算法机器人栅格地图最短路径规划【含Matlab源码 119期】

    ⛄一.简介 路径规划是实现移动机器人自主导航的关键技术,是指在有障碍物的环境中,按照一定的评价标准(如距离.时间.能耗等),寻找到一条从起始点到目标点的无碰撞路径,这里选取最短距离路径规划的评价标准, ...

  8. 【路径规划】基于matlab蚁群算法机器人大规模栅格地图最短路径规划【含Matlab源码 1860期】

    ⛄一.蚁群算法及栅格地图简介 随着机器人技术在诸多领域的应用, 如机器人协作焊接.灾后搜救.军事.太空探索.深海勘探.家用和服务行业等, 机器人的发展正向智能化方向延伸, 要求其具有自组织.自学习.自 ...

  9. 【路径规划】基于matlab蚁群算法栅格地图路径规划及避障【含Matlab源码 2088期】

    一.蚁群算法及栅格地图简介 随着机器人技术在诸多领域的应用, 如机器人协作焊接.灾后搜救.军事.太空探索.深海勘探.家用和服务行业等, 机器人的发展正向智能化方向延伸, 要求其具有自组织.自学习.自适 ...

最新文章

  1. 【extjs6学习笔记】1.1 初始:创建项目
  2. ReSIProcate源码目录下功能说明
  3. 5.关于QT中的网络编程,QTcpSocket,QUdpSocket
  4. 数据湖三种方案的流行度调查
  5. 什么是自愈环网光端机?
  6. Pytorch高阶API示范——线性回归模型
  7. java 名词解释等
  8. mysql 恢复空密码_mysql 找回密码
  9. python学什么方向就业好_学python就业都有哪些方向
  10. Inno Setup 操作XML
  11. Caffe for Python 官方教程(翻译)
  12. Vue 全站缓存之 vue-router-then :前后页数据传递
  13. 二进制二进制编辑器_为什么十六进制编辑器称为二进制编辑器?
  14. TOGAF9中文版(二)
  15. Struts中动态ActionForm与静态ActionForm有什么区别?_
  16. python_opencv_haze加雾处理
  17. 计算机专业英语朱龙主编,计算机专业英语(高职高专计算机系列)
  18. Acwing-4454. 未初始化警告
  19. 心跳重连机制(登录)
  20. 非托管内存转换为System.Drawing.Bitmap

热门文章

  1. oracle预算,ORACLE EBS 标准功能预算功能和实例
  2. 1971: 安排座位
  3. 导电滑环的作用是什么
  4. Aspose生成pdf文档,linux乱码解决
  5. 三羊献瑞+祥瑞生辉(15年蓝桥杯)
  6. 关于垃圾收集器G1与ZGC
  7. 华硕天选3锐龙版和酷睿版哪个好
  8. 地球引擎初级教程——Google Earth Engine计算最简单的多边形面积和周长计算
  9. HTML页面怎么添加水印?
  10. 太鸡冻了!我用Python偷偷查到暗恋女生的名字