蚁群算法路径搜索初探

        最近任务需要,学习路径搜索,先是看了A*算法,然后自己又研究了下蚁群算法。

        我是在三维网格地图中实现的路径搜索,用的点而不是边来标记信息素的,主要是觉得边要麻烦一些,感兴趣的可以自己实现边标记信息素。蚂蚁在三维地图中走,每次可以上下,左右,斜着走,且都算作等效的一步距离。

1.原理

        用到的公式如下:

                                                                    (1)

                                                            (2)

                                                                            (3)

        这两个是基础公式,表示信息素的更新过程,(1)分别更新,该蚂蚁走过的路径中的信息素,(2)信息素的改变值是用一个常数Q除以该蚂蚁路径的长度,然后再。未走过的点更新值为0。(3)在自然界中蚂蚁遗留下来的信息素经过一段时间后会挥发,我们在算法中也模拟上述过程

主要步骤:

1.      首先要初始化一群蚂蚁和信息素,初始值设为1。

2.      每一只蚂蚁的时候按照信息素的轮盘赌算法,或者锦标赛算子走下一步。

3.      每一轮所有蚂蚁走完路径后,更新所有路径上的信息素。

4.      同时环境以一定的速率让信息素消失(信息素的挥发)。

5.      这样循环往复,蚂蚁们就有可能走出一条最优路径。

在此基础上加入了精英蚂蚁策略,每轮路径最优的蚂蚁,获得额外的信息素更新。

                                                        (4)


2.规划每只蚂蚁的路径

        首先初始化信息素。

//初始化信息素
		for(int i=0;i<x_len;i++){
			for(int j=0;j<y_len;j++){
				for(int k=0;k<z_len;k++){
					pheromones[i][j][k] = initalPher;
				}
			}
		}

        我们可以看做蚂蚁处在魔方的中间,魔方表面的块,就是下一步可以移动的点。为了避免蚂蚁来回,重复走,每走一步将前一步可选的26个点都标记。
private static Ant planPath(Point start,Point end,double[][][]pheromones,int[][][] map){
		
		int x_len = map.length;
		int y_len = map[0].length;
		int z_len = map[0][0].length;
		//规划路径
		int tmp_x = start.getX() ,tmp_y = start.getY(),tmp_z = start.getZ();
	
		int[][][] mark = new int[x_len][y_len][z_len];//每只蚂蚁走过后重置
		Ant ant = new Ant();
		
		while(tmp_x!=end.getX() || tmp_y!= end.getY() || tmp_z!= end.getZ()){
			

			mark[tmp_x][tmp_y][tmp_z] = -1;///表示此处已经计算过了
			ArrayList<Point> availablePoint = new ArrayList<>();
			//寻找可达的点
			for(int h=-1;h<=1;h++){
				for(int w=-1;w<=1;w++){
					for(int t=-1;t<=1;t++){
						
						int next_x = tmp_x + h;	///下一个将加入open 集的格子的i
						int next_y = tmp_y + w;///下一个将加入open 集的格子的j
						int next_z = tmp_z + t;///下一个将加入open 集的格子的k
						
						if(next_x>=0 && next_x<=x_len-1 && next_y>=0 && next_y<=y_len-1 && next_z>=0 && next_z<=z_len-1){
							数组不越界,则进行计算
							if(map[next_x][next_y][next_z]== obstacle || mark[next_x][next_y][next_z]==-1 ||(h==0&&w==0&t==0)){
								//如果该格子是障碍,或者格子本身,跳过
								continue;
							}
							availablePoint.add(new Point(next_x,next_y,next_z));
//								if(t!=0 && (h!=0 || w!=0)){
//									continue;
//								}
						
							mark[next_x][next_y][next_z] = -1;///表示此处已经计算过了
						}				
					}
				}		
			}
			
//			int m = roulette(availablePoint,pheromones);
			int m = jingbiaosai(availablePoint,pheromones);
			//如果无路可走,重新从起点开始规划,,标记清零,路径清零
			if(m==-1){
				
				tmp_x = start.getX();
				tmp_y = start.getY();
				tmp_z = start.getZ();
				
//					for(Point p1:ant.getPath()){
//						mark[p1.getX()][p1.getY()][p1.getZ()] = 0;
//					}
				mark = new int[x_len][y_len][z_len];//每只蚂蚁走过后重置
				ant.setPath(new ArrayList<Point>());
				
			}else{
				
//					System.out.print("选择的点:"+m+" ");
				//轮盘赌选择下一个点
				Point nextPoint = availablePoint.get(m);
				//更新当前位置
				tmp_x = nextPoint.getX();
				tmp_y = nextPoint.getY();
				tmp_z = nextPoint.getZ();
//				System.out.print("("+tmp_x+","+tmp_y+","+tmp_z+")");
				
				ant.getPath().add(nextPoint);//添加路径
				mark[tmp_x][tmp_y][tmp_z] = -1;//走过了,标记
			}
			
		}
//		System.out.println();
		return ant;
			
		
	}

        选择下一步使用锦标赛算子,如下

private static int jingbiaosai(ArrayList<Point> availablePoint,
			double[][][] pheromones) {
		int len = availablePoint.size();
		if(len==0)
			return -1;
		int a = (int) (Math.random()*len);
		int b = (int) (Math.random()*len);
		Point A = availablePoint.get(a);
		Point B = availablePoint.get(b);
		
		if(pheromones[A.getX()][A.getY()][A.getZ()]> pheromones[B.getX()][B.getY()][B.getZ()])
			return a;
		else 
			return b;
	}

        经过多轮的迭代后,输出最后一轮中的最佳结果。

3.总结与感想

        通过自己的练习,对蚁群算法有了较为深刻的理解,发现蚁群算法和遗传算法有着许多相似之处。现在的缺点是运行时间慢,需要优化代码的效率。感兴趣的可以下载代码,代码链接如下:

https://download.csdn.net/download/mtngt11/10423686

请大家多多支持哟


  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值