蚁群算法求解迷宫最优路径问题
来源:互联网 发布:商业分析师 知乎 编辑:程序博客网 时间:2024/04/29 07:08
本段程序的基本思想是利用蚁群算法中的蚁周模型,来对全局的迷宫图进行信息素的跟新
和为每一只蚂蚁选择下一个方格。 一共会进行RcMax = 2000轮模拟(理论上模拟的次数越多结果
会越接近真实值),而在每一轮中会排除 M = 10只蚂蚁进行探路。同时在算法的回溯思想上采用的
是栈的数据结构来实现的。当栈最终为空时则表示无解。但同时这段程序的一缺点就是:由于我没在
算法中对每一轮的每只探路蚂蚁采用多线程的模式,所以整体的运行效率还不是很高。如读者有好的
思想或建议,请留言。
#include<iostream>#include<stack>#include<bitset>using namespace std;//坐标类struct Point{int x;int y;};//地图类template<int A,int B>class Map{public:int (*p)[B];//1表示为障碍方格,0表示该方格可通bitset<4> (*around)[B];//记录每一个方格四周四个方法的可选标记int row;//行数int col;//列数Map(){p =new int[A][B];around = new bitset<4>[A][B];}Map(Map<A,B> & B1){ p =new int[A][B]; around = new bitset<4>[A][B]; row = B1.row; col = B1.col; for(int i = 0;i<row;i++) { for(int j = 0;j<col;j++) { p[i][j] = B1.p[i][j]; around[i][j] = B1.around[i][j]; } }}Map<A,B> & operator=(Map<A,B> & B1){ row = B1.row; col = B1.col; for(int i = 0;i<row;i++) { for(int j = 0;j<col;j++) { this->p[i][j] = B1.p[i][j]; around[i][j] = B1.around[i][j]; } } return *this;}};//start起始点, end终止点template<int A,int B>bool FindPath(Map<A,B> & map,Point & start,Point & end){const int N1 = A;const int N2 = B;const int M = 10;//每一轮中蚂蚁的个数const int RcMax = 2000;//迭代次数const int IN = 1;//信息素的初始量double add[N1][N2];//每一段的信息素增量数组double phe[N1][N2];//每一段路径上的信息素double MAX = 0x7fffffff;double alphe,betra,rout,Q;//alphe信息素的影响因子,betra路线距离的影响因子,rout信息素的保持度,Q用于计算每只蚂蚁在其路迹留下的信息素增量double bestSolution = MAX;//最短距离stack<Point> Beststackpath;//最优路线//初始化变量参数和信息数组alphe = betra = 2;rout = 0.7;Q = 10;//先给图的外围加上障碍for(int i = 0;i<map.col;i++){map.p[0][i] = map.p[map.row-1][i] = 1;}for(int i = 0;i<map.row;i++){map.p[i][0] = map.p[i][map.col-1] = 1;}//初始化图中每一个方格的四周访问表示位,0表示可访问//初始化信息素数组for(int i = 0;i<N1;i++ ){ for(int j = 0;j<N2;j++) {phe[i][j] = IN;map.around[i][j].reset();//4个方向全部设为可选 }}//用于方向选择的偏移量数组 按照顺时针的方向Point offset[4];offset[0].x = 0; offset[0].y = 1;//向右offset[1].x = 1; offset[1].y = 0;//向下offset[2].x = 0; offset[2].y = -1;//向左offset[3].x = -1; offset[3].y = 0;//向上//每轮M只蚂蚁,每一轮结束后才进行全局信息素更新stack<Point> stackpath[M];//拷贝障碍地图Map<A,B> Ini_map[M];//记录每一只蚂蚁的当前位置Point Allposition[M];int s = 0;while(s<RcMax)//一共RcMax轮{//先清空每一只蚂蚁的路线存储栈for(int i = 0;i<M;i++){while (!stackpath[i].empty()){stackpath[i].pop();}}for(int i = 0;i<M;i++){Ini_map[i] = map;//将起点初始化为障碍点 Ini_map[i].p[start.x][start.y] = 1;//起点入栈 stackpath[i].push(start);//初始化每一只蚂蚁的当前位置Allposition[i] = start;}//开启M只蚂蚁循环 for(int j = 0;j<M;j++) { while(((Allposition[j].x)!=(end.x)||(Allposition[j].y)!=(end.y))) { //选择下一步 double psum = 0; for(int op = 0;op<4;op++) {//计算下一个可能的坐标int x = Allposition[j].x + offset[op].x;int y = Allposition[j].y + offset[op].y; if((Ini_map[j].around[ Allposition[j].x][Allposition[j].y])[op]==0 && Ini_map[j].p[x][y] !=1) { psum += pow(phe[x][y],alphe) * pow((10.0/stackpath[j].size()),betra); } } //判断是否有选择 //如找到了下一点 if(psum!=0) { double drand = (double)(rand())/(RAND_MAX+1); double pro = 0; int re; int x,y; for( re = 0;re<4;re++) { //计算下一个可能的坐标 x = Allposition[j].x + offset[re].x; y = Allposition[j].y + offset[re].y; if((Ini_map[j].around[ Allposition[j].x][Allposition[j].y])[re]==0 &&Ini_map[j].p[x][y]!=1) { pro += (pow(phe[x][y],alphe) * pow((10.0/stackpath[j].size()),betra))/psum; if(pro>=drand) { break; } } } //入栈 Allposition[j].x = x; Allposition[j].y = y; stackpath[j].push(Allposition[j]); //设置障碍 Ini_map[j].p[Allposition[j].x][Allposition[j].y] = 1; } else//没找到了下一点 { //向后退一步,出栈 stackpath[j].pop(); //消除入栈时设置的障碍 Ini_map[j].p[Allposition[j].x][Allposition[j].y] = 0; if(stackpath[j].empty()) { return false; } //设置回溯后的Allposition if(Allposition[j].x == stackpath[j].top().x) { if((Allposition[j].y - stackpath[j].top().y)==1)//向右 { (Ini_map[j].around[ stackpath[j].top().x][stackpath[j].top().y])[0] = 1;//标记该方向已访问 } if((Allposition[j].y - stackpath[j].top().y)==-1)//向左 { (Ini_map[j].around[ stackpath[j].top().x][stackpath[j].top().y])[2] = 1;//标记该方向已访问 } } if(Allposition[j].y == stackpath[j].top().y) { if((Allposition[j].x - stackpath[j].top().x)==1)//向下 { (Ini_map[j].around[ stackpath[j].top().x][stackpath[j].top().y])[1] = 1;//标记该方向已访问 } if((Allposition[j].x - stackpath[j].top().x)==-1)//向上 { (Ini_map[j].around[ stackpath[j].top().x][stackpath[j].top().y])[3] = 1;//标记该方向已访问 } } Allposition[j].x = stackpath[j].top().x; Allposition[j].y = stackpath[j].top().y; } } }//保存最优路线double solution = 0;for(int i = 0;i<M;i++){solution = 0;solution = stackpath[i].size();if(solution<bestSolution){ Beststackpath = stackpath[i]; bestSolution = solution;}}//计算每一只蚂蚁在其每一段路径上留下的信息素增量//初始化信息素增量数组for(int i = 0;i<N1;i++){ for(int j = 0;j<N2;j++) { add[i][j] = 0; }}for(int i = 0;i<M;i++){ //先算出每只蚂蚁的路线的总距离solu double solu = 0; solu = stackpath[i].size(); double d = Q/solu; while(!stackpath[i].empty()) { add[stackpath[i].top().x][stackpath[i].top().y] += d; stackpath[i].pop(); }}//更新信息素for(int i=0;i<N1;i++){ for(int j = 0;j<N2;j++) { phe[i][j] = phe[i][j]*rout + add[i][j]; //为信息素设置一个下限值和上限值if(phe[i][j]<0.0001){phe[i][j] = 0.0001;}if(phe[i][j]>20){phe[i][j] = 20;} }}s++;}//轮//找到路径,并输出stackpathcout<<"找到最优路径!"<<endl;cout<<"最短路线长度为: 共"<<Beststackpath.size()<<"个方格!"<<endl;while(!Beststackpath.empty()){cout<<"<"<<Beststackpath.top().x<<","<<Beststackpath.top().y<<">"<<endl;Beststackpath.pop();}return true;}int main(){//建立迷宫Map<10,10> map;map.col = map.row = 10;int p[10][10];for(int i =0;i<10;i++)//初始化迷宫{ for(int j=0;j<10;j++) { p[i][j] = 0; }}//为迷宫设置障碍p[1][3] = 1;p[1][7] = 1;p[2][3] = 1;p[2][7] = 1;p[3][5] = 1;p[3][6] = 0;p[4][2] = 1;p[4][3] = 1;p[4][4] = 1;p[5][4] = 1;p[6][2] = 1;p[6][6] = 1;p[7][2] = 1;p[7][3] = 1;p[7][4] = 1;p[7][6] = 1;p[8][1] = 1;map.p = p ;Point start,end;start.x = start.y = 1;end.x =8,end.y = 8;if(!FindPath<10,10>(map,start,end)){ cout<<"该迷宫无解!"<<endl;}}
6 1
- 蚁群算法求解迷宫最优路径问题
- 迷宫求解最优路径
- AStar算法求解迷宫最短路径问题
- 栈-迷宫求解路径问题
- 迷宫矩阵(最优路径算法)
- 经典算法<一>迷宫问题 4.多条路径 求路径条数求解 C++实现
- 数据结构--用栈求解迷宫问题(非最优解)
- 关于迷宫求解及其最优解的问题
- [数据结构]求解迷宫最短路径问题
- 迷宫的最优路径
- 经典算法<一>迷宫问题 1.单条路径 DFS求解 C++实现
- 经典算法<一>迷宫问题 2.单条路径 BFS求解 C++实现
- 经典算法<一>迷宫问题 3.多条路径 BFS求解 C++实现
- 自己实现迷宫算法并且打印出最优路径
- 使用栈解决迷宫问题(不是最优路径)php
- 数据结构-迷宫求解路径
- 迷宫最优解问题
- 深搜,迷宫求最优路径
- 在水晶报表中如何显示Checkbox的样式
- 用GDB调试程序 - Ubuntu中文
- JWPlayer快速入门指南(中文)
- 努力成为布道者
- 第四章作业
- 蚁群算法求解迷宫最优路径问题
- Struts2教程9:实现自已的拦截器
- 第九周作业(1)
- IE中的条件注释
- python十分钟入门
- VS2010 编译器的数值计算bug
- OD常用断点设置(来自网络)
- minihomepage.exe 百度影音迷你首页
- spring bean标签,及其子标签使用 (转载)