蚁群算法求解迷宫最优路径问题

本段程序的基本思想是利用蚁群算法中的蚁周模型,来对全局的迷宫图进行信息素的跟新

和为每一只蚂蚁选择下一个方格。 一共会进行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++;
	}//轮

	//找到路径,并输出stackpath
	cout<<"找到最优路径!"<<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;
	}
}

蚁群算法求解迷宫最优路径问题,布布扣,bubuko.com

时间: 2024-10-11 17:22:22

蚁群算法求解迷宫最优路径问题的相关文章

ACS蚁群算法求解对称TSP旅行商问题的JavaScript实现

本来以为在了解蚁群算法的基础上实现这道奇怪的算法题并不难,结果实际上大相径庭啊.做了近三天时间,才改成现在这能勉强拿的出手的模样.由于公式都是图片,暂且以截图代替那部分内容吧,mark一记. 蚁群算法解TSP问题的javascript实现 目录(又是神奇的手动目录..) 1 蚁群算法 (1)        蚁群AS算法简介 (2)        蚁群AS算法过程 (3)        蚁群AS算法TSP问题应用 (4)        蚁群算法应用于TSP步骤 2 蚁群系统(Ant Colony

蚁群算法求解旅行商问题(附c和matlab源代码)

前几天写了个模拟退火算法的程序,然后又陆陆续续看了很多群智能算法,发现很多旅行商问题都采用蚁群算法来求解,于是开始写蚁群算法的模板.网上关于蚁群算法的理论很多就不再这里赘述了,下面直接上代码和进行简单的比较. c代码: 1 #ifndef _CITY_H 2 #define _CITY_H 3 struct CITY 4 { 5 int id; 6 double x, y; 7 }; 8 #endif // !_CITY_H CITY.h 1 #ifndef _OPTION_H 2 #defin

利用HTML5 Canvas和Javascript实现的蚁群算法求解TSP问题演示

HTML5提供了Canvas对象,为绘图应用提供了便利. Javascript可运行于浏览器中, 而不需要安装特定的编译器: 基于HTML5和Javascript语言, 可随时编写应用, 为算法测试带来便利. 针对TSP问题, 编写了Ant colony algorithm, 用于演示该算法, tsp_ant_colony_algorithm.html代码如下: <html> <head> <meta charset = "utf-8" / > &l

蚁群算法求解TSP问题

蚁群算法的第一个算法就是蚂蚁系统,而蚂蚁系统有三种基本模型分别是 蚁周模型.蚁密模型.蚁量模型.三种模型的实现大致相同,主要区别是在信息素 的更新方式上.在用蚂蚁系统解决T SP问题时,蚁量模型和蚁密模型是蚂蚁在构建 一条合法路径的过程中进行信息素的更新的,当蚂蚁走过一条边之后,就对该边进 行信息素的更新,即为局部更新方式.而蚁周模型是在所有蚂蚁都构建了一条合 法路径之后才对各边进行信息素更新的,也即全局更新方式. 并且这三种模型中蚂蚁在自己所走过的路线上释放的信息素的量也是有所 不同的,在蚁密

蚁群算法解决TSP问题

一.论述 1.算法来源 蚁群算法的基本原理来源于自然界蚂蚁觅食的最短路径原理,根据昆虫学家的观察,发现自然界的蚂蚁虽然视觉不发达,但它可以在没有任何提示的情况下找到从食物源到巢穴的最短路径,并且能在环境发生变化(如原有路径上有了障碍物)后,自适应地搜索新的最佳路径. 2.单个蚂蚁寻找路径 正反馈: 单个的蚂蚁为了避免自己迷路,它在爬行时,同时也会释放一种特殊的分泌物--信息素(Pheromone),而且它也能觉察到一定范围内的其它蚂蚁所分泌的信息素,并由此影响它自己的行为.当一条路上的信息素越来

蚁群算法和简要matlab来源

1 蚁群算法原理 从1991由意大利学者 M. Dorigo,V. Maniezzo 和 A. Colorni 通过模拟蚁群觅食行为提出了一种基于群体的模拟进化算法--蚁群优化.极大关注,蚁群算法的特点: ① 其原理是一种正反馈机制或称增强型学习系统; 它通过[最优路径上蚂蚁数量的添加→信息素强度添加→后来蚂蚁选择概率增大→最优路径上蚂蚁数量更大添加]达到终于收敛于最优路径上L ② 它是一种通用型随机优化方法, 它吸收了蚂蚁的行为特(内在搜索机制) , 它是使用人工蚂蚁仿真(也称蚂蚁系统) 来求

蚁群算法简介及应用

蚂蚁几乎没有视力,但他们却能够在黑暗的世界中找到食物,而且能够找到一条从洞穴到食物的最短路径.它们是如何做到的呢? 简介 由来 蚁群算法是一种用来寻找优化路径的概率型算法.它由Marco Dorigo于1992年在他的博士论文中提出,其灵感来源于蚂蚁在寻找食物过程中发现路径的行为. 这种算法具有分布计算.信息正反馈和启发式搜索的特征,本质上是进化算法中的一种启发式全局优化算法. 思想 将蚁群算法应用于解决优化问题的基本思路为:用蚂蚁的行走路径表示待优化问题的可行解,整个蚂蚁群体的所有路径构成待优

智能算法---蚁群算法

智能算法---蚁群算法 1 蚁群算法及其基本思想 蚁群算法是一种智能优化算法,通过蚁群优化求解复杂问题,ACO在离散优化问题方面有比较好的优越性. 基本思想(以旅行商问题为例) 设置多只蚂蚁,分头并行搜索. 每只蚂蚁完成一次周游后,在行进的路上释放信息素,信息素量与解的质量成正比. 蚂蚁路径的选择根据信息素强度大小(初始信息素量设为相等),同时考虑两点之间的距离,采用随机的局部搜索策略.这使得距离较       短的边,其上的信息素量较大,后来的蚂蚁选择该边的概率也较大. 每只蚂蚁只能走合法路线

基本蚁群算法

//=====================================================================//基本蚁群算法源代码//使用的城市数据是eil51.tsp//=====================================================================// AO.cpp : 定义控制台应用程序的入口点.#pragma once#include "stdafx.h"#include <ios