UVA1601 The Morning after Halloween

这篇博客介绍了如何解决UVA1601问题,利用状态压缩、双向BFS和A*算法进行搜索。通过提取空格坐标减少判断,双向BFS同步起点和终点,A*算法优化搜索路径。文章提供了编码和解码方法,以及A*算法的实现细节,强调在更新open_list时的注意事项。
摘要由CSDN通过智能技术生成

UVA1601 The Morning after Halloween(状态压缩,双向bfs,A*)

本题属于搜索类题,通过bfs去枚举状态,从而找到解。然而该题的状态数上限是256的三次方,状态转移有5的3次方个转移方法,转移代价高。解决方法:
1、因为题目保证每2×2个方格一定有一个障碍,所以可以将所有空格提取出来。目的是在状态转移时不用每次去判断条件(越界、有障碍)。
具体步骤:
(1)、是将原图的每个空格的坐标保存到另外一个数组,并将空格编号。
(2)、开辟一个二维数组G[x][y],x表示当前空格的编号,y表示转向,取值0~4,表示有几种转移路径可选,G[x][y]的值表示在x空格通过y转移路径(你无需直到y的具体转移方法)能到达的另一个空格的编号。用trans[x]来表示编号为x的空格的转移路径的数目。
这样在搜索的过程中就无需进行重复判断了。
2、双向bfs,将起点和终点同时放进队列。起点的step设为0,终点的step设为1.将从起点出发的vis值设为1,从终点出发的vis值设为2,将没有访问过的vis值设为0;当现节点的vis+相邻节点的vis==3时,答案即为step之和。
3、A*算法。
(1)将起点加入open_list
(2)当open_list不为空:
(3)选取open_list中f值最小的节点
(4)如果该节点为终点,则打印路径,结束循环;
(5)遍历当前节点的周围节点:
如果周围的节点在close_list中或者是不可到达的点,则跳过;
如果周围的节点不在open_list中,加入open_list,计算f值,并将当前节点作为其父节点;
如果周围节点在open_list中,比较经由当前节点的f值和原f值:如果经由当前节点的f值更小,则更新该节点的父节点为当前节点,更新f值;
(6)如果满足条件2,重复上述3~5步骤

锦上添花之举:
1、用编码(encoding)的方法将每个状态(节点的位置)压缩成一个整数再放进队列;取出来的时候再解码(decoding)。具体方法:
题目最大图为16×16,如果给空格编号,则每个小写字母可能出现的位置所在的最大空格标号为16×16=256=2的8次方,所以可以用一个8位的2进制数去表示一个点的位置。

A*算法实现代码如下(320ms):

#include<iostream>
#include<cstring>
#include<cmath> 
#include<cstdio> 
#include<cstdarg>
#include<queue>
using namespace std;
char dataset[20][20];
int G[200][5];
int trans[200];
int w,h,n;
int s[3],t[3];
int x[200],y[200],id[20][20];
int dx[5]={
   0,1,-1,0,0};
int dy[5]={
   0,0,0,1,-1};
const int d=0xff;
int dist_2[200][3];//图上每个点到终点的距离 
int min_f[200][200][200];//记录最小f值,用于比较原f和现有最优f 
struct Node{
   
	int state;//状态 
//	int fx;//估值函数,选取节点包含的三个点到终点的最大距离作为启发函数h(x)的值 
	int gx;//已知代价函数 
	int hx;//启发函数 
	Node(int a,int b,int c):state(a),gx(b),hx(c){
   };
	bool operator <
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值