- 1、本文档共5页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
滚动广搜的简单介绍
滚动广搜
我们知道朴素广搜的空间浪费很严重,原因很简单,朴素广搜将从初始节点开始可以达
到的所有状态全都记录下来了,而这样需要消耗的空间代价是指数级的。所有使用广搜时,
空间就显得很宝贵。于是我们开始寻找对状态储存的优化,以减小对空间的消耗。一类典型
的题目(求迷宫中到达某一个位置的最少步数),可以用到一种思想———滚动广搜。
滚动广搜的思想就是用到两个表来储存前一个阶段可以达到的所有状态和当前阶段可
以达到的所有状态。因为这一步能到达的所有位置只由上一步的位置决定,而所有的位置的
集合规模是 n*m(分别表示迷宫的长和宽)。我们只需要开两个大小为 n*m 的表就可以保证
能记录所有可能达到的位置了。每次取出前一阶段所有状态节点,并按照产生式规则对其扩
展并存入当前阶段的表内。然后通过 now:=1-now 不断切换前一阶段与当前阶段,(注意:每
次要对当前阶段的表和标记数组进行清空)。
1.下面给出滚动广搜的数据结构:
type rec=record{节点的描述,包括横纵、坐标,根据题目不同可适当添加}
x,y:integer;
end;
var q:array[0..1,1..maxn*maxm] of rec; {0、1 分别表示当前阶段和前一个阶段}
r:array[0..1] of longint; {两个表对应的尾指针}
used:array[1..maxn,1..maxm] of Boolean;{标记(u,v)是否以可到达}
2.以下是滚动广搜的核心算法部分。
procedure rollbfs;
var i,f,u,v:integer;
begin
now:=0;r[now]:=1;q [now,1].x:=fx;q[now,1].y:=fy;{初始化,将起点位置入队}
repeat
now:=1-now; r[now]:=0;
fillchar(used,sizeof(used),0);
{切换到当前阶段,置队列为空,将 used 标记数组清空}
for f:=1 to r[1-now] do{取出前一阶段的所有状态节点并对其进行扩展}
begin
for i:=1 to maxway do{枚举对于该位置所有可能的扩展方向}
begin
u:=q[1-now,f].x+a[i];{a,b 分别为横、纵方向上的增量}
v:=q[1-now,f].y+b[i];
if (map[u,v]可达到) and(not(used[u,v]){(u,v)未被标记过} then
begin
inc(r[now]); if (r[now]n*m) then exit;
q[now,r[now]].x:=u;,
q[now,r[now]].y:=v;
used[u,v]:=true;
if (u=ex)and(v=ey) then{如果达到终点则打应并结束算法}
begin writeln(time);close(output);halt; end;
end;
end;
end;
until 01;
end;
参考题目:《穿越封锁线》《最后的战犯》《SEARCH》《迷宫》
附:
最后的战犯
题目描述:话说 Lucky和 Feli 以 3721 部队为诱饵,歼灭
文档评论(0)