[计算机]1 深度优先搜索 DFS
?1 深度优先搜索 DFS
我优在优一些优优优行求解优~优优有些优优优优到优律~或者根本无优律可优。优于优优的优优~可以利用优会很找
算机算速度快的特点~先搜索优所有可能出优的情~再根据优目件所有可能的情中~运找况条从况
优除那些不符合件的解。条
【例优1】 有A、B、C、D、E 5本优~要分优优、王、、优、优刘5位同~每人只能优学1本。每个人都自己喜优的优在下表中。优优优一程序~打印出优每人都优意的所有分优
方案
气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载
。将填写你个个
????????????????????????
? ? , ? , ? : ? , ? , ?
????????????????????????
? 优? ? ? ? ? ? ? ?
????????????????????????
? 王? ? ? ? ? ? ? ? ?
????????????????????????
? ? ? ? ? ? ? ? ?刘
????????????????????????
? 优? ? ? ? ? ? ?
????????????????????????
? 优? ? ? ? ? ? ? ?
?????????????????????????优优分析
优目中每人喜优本优是意的~无优律可循~所以用优优方法解优优合适。按优优法的一般算法~哪随
可以优不考优一些件~先求出优足部分件的解~可行解。然后~再加上未考优的件~条条即尚条从
可行解中优除不符合优些件的解~留下的就是优优的解。具到本优中~我优可以先不考优“优每人条体
都优意”优件~优优~就只剩“每人优一本且只能优一本”优一件了。在优件下~可行解个条个条个条
是5本优的所有全排列~一共有5!=120优情。优况从120优可行解中优去不符合“每人都优意”优一条件的解~剩下的就是本优的解。
优优程方便~我优用1、2、3、4、5分优表示优5本优。优5字的优全排列就是个数—5本优的一优分法。例如54321就表示第五本优(即E)分优优~第四本优(即D)分优王……~第本优—(即A)分优优。
每人“喜优优表”~在程序中我优用二优优个数Like表示~来1表示喜优~0表示不喜优。排列的优生可以用优优法~也可以用优优算法。
?算法优优,
第一步,优生5字的一全排列~个数个
第二步,优优所优生的全排列是否符合“喜优优表”~如果符合就优出~
第三步,优优是否所有排列都优生了~如果有优生完~优返回第一步~没
第四步,优束。
根据优目优出的件~优可以优上面算法优行一些改优。例如优生一全排列条个12345优~第一个数1表示第一本优优小优。但表中可以看出~优是不可能的~因优小优只喜优第三、第四本优。也就是优将从~,X X X X优一优分法是不符合件的。由此使我优想到~如果优定第一本优后~就立优优一下是条即
否符合件~优优第一的优优不符合件优~就不必再优生后面的条当个数条4了~优优做可以少个数减很多的算量。优句优优~第一只在运个数3和4中优优~优优就可以少减3,5的算量。同理~在优定了运第一后~其他个数4字的优优也可以用优似的方法优理~优优第二后~立优优是否符合个数即个数即条
件。例如~第一优个数3~第二优个数4后~立优行优优~优优不符合件~就优第二。优优就又把即条另个数
34XXX一优的分法优去了~而又少了一部分算量。从减运
优上所述~改优后本优算法优优是,在优生各优排列优~每增加一字~就优优一下优的加入是否个数数
符合件~如不符合~就立刻优一~若符合件~优再优生下一。因优第条个条个数从i本优到第i+1本优的优优程是相同的~所以可以用优优方法优程。找
?算法优框
PROCEDURE TRY(i)~(优优算法)
???????????????????????
? For j:= 1 to 5 do ?
???????????????????????
? ? T ,第I生喜优第个学j本优, F ?
? ?????????????????????
? ? 优优第 i ? ?个数
? ?????????????? ?
? ? , i= 5 , ? ?
? ? T , , F ? ?
? ?????????????? ?
? ?打印一解? 个Try(i+1) ? ?
? ?????????????? ?
? ? 优去第i 字 ? ?个数
???????????????????????
我优用二优优数like存放“喜优优表”~用集合flag存放已分出优的优~优号数book存优各人所分得优的优~如号book[1]=3~优表示第一同个学(小优)分得优优号3的优。
优优程序如下(程序中小优的喜优的优改成了将ACD),
Program allot_book(output);
type five=1..5;
const like: array[five,five] of 0..1 =((1, 0, 1,1 ,0),
(1,1,0,0,1),(0,1,1,0,0),(0,0,0,1,0),(0,1,0,0,1));
{人优各优优的喜好情个况}
name:array[five] of string[5] =
('zhang', 'wang','liu', 'zhao', 'qian' );
{优数name存放生姓名学}
var book: array[1..5] of 0..5;{存放各人分配到的优的优号}
flag: set of five;
c: integer;
procedure print; {打印分配方案}
var i: integer;
begin
inc(c); {优~优优得到分配方案数数}
writeln( 'answer', c,':');
for i:=1 to 5 do
writeln(name[i]: 10,':', chr(64 + book[i] ) );
end;
procedure try(i: integer); {判第 断I 生分得优的优个学号}
var j: integer;
begin
for j:=1 to 5 do
if not(j in flag) and (like[i,j]>0) then
begin {第j本优未优优~且第I生喜优第个学j本优}
flag:= flag + [j]; {修改已优优优集合~加入第号j本优}
book[i]:=j; {优优第 I 生分得优的优个学号}
if i= 5 then print {I = 5,5 生都分到自己喜优的优个学}
else try(i + 1);
{i<5,优优搜索下一生可能分到优的情个学况}
flag:= flag - [j]; {后退一步~以便优下一优分配方案找}
book[i]:=0;
end
end;
{ main prg }
begin
flag:= [];
c:=0;
try(1);
readln
end.
运行优果优:
zhang: C
wang: A
liu:B
Zhao: D
qian: E
另来号外~此优也可以用非优优的算法解。非优优算法的基本思想是用优存放被优中优的优。优dep表示搜索深度~r优待优优~号p优搜索成功优志。算法表示如下;非优优算法,。
PROCEDURE dfs~(非优优算法)
??????????????????????????????
? Dep:=0 ?
??????????????????????????????
? ? dep:=dep+1 ?
? ????????????????????????????
? ? j:=0; p:=False~ ?
? ????????????????????????????
? ? ? j:=j+1 ?
? ? ??????????????????????????
? ? ? T ,子优点mr符合优优, F ?
? ? ??????????????????????????
? ? ? 优生子优点~优优 ? 并T ,Mxar, F ?
? ? ??????????????????????????
? ? ? T ,子优点是目优, F ? 回溯 ?P:=Fatse?
? ? ???????????????? ? ?
? ? ? 优出出优? 并P:= true ? ? ?
? ????????????????????????????
? ? UNTIL p=True ?
??????????????????????????????
? UNTIL dep= 0 ?
??????????????????????????????
尽体尽管深度优先基本算法优似~但在优理不同优优优~在具优理方法、优程的技巧上~却不相同~
有优甚至会很有大的差优。
比如~例1的解法优可以优优优优,表中看出~优同只喜优来从学D优一本优~无其优优它余地。因此~优同得到优的优在搜索学号确来前就定下了。优了优程方便~可以把优优2人位置交优~优优程序只需优优王优刘4人情优行搜索优优。况
另数个外~优优表示“喜优优表”的优有多0~优少不必要的优减来探~我优改用优表表示。例如第三位同的优表是,学Like[3~0]=2.Like[3~2]=3.Like[3~3]=0~其中~Like[3~0]=2 表示他喜优
的第一本优优是号2~Like[3~2]=3表示喜优的优优即号2的优后面是优优号3的优~Like[3~3]=0~ 表示优优号3的优是其最后1本喜优的优。
优优基本算法不优~但程序改优如下,
Program allot_book(output); {linking List}
type five=1..5;{小优的喜优的优改成了将ACD}
const Link: Array[ 1..5,0..5 ] of 0..5 =
((1,3,0,4,0,0),(1,2,5,0,0,0),(2,0,3,0,0,0),(4,0,0,0,0,0),(2,0,5,0,0,0));
{人优各优优的喜好情个况}
name:array[five] of string[5] =
('zhang', 'wang','liu', 'zhao', 'qian' );
{优数name存放生姓名学}
var book: array[1..5] of 0..5;{存放各人分配到的优的优号}
flag: set of five;
c: integer;
procedure print; {打印分配方案}
var i: integer;
begin
inc(c); {优~优优得到分配方案数数}
writeln( 'answer', c,':');
for i:=1 to 5 do
writeln(name[i]: 10,':', chr(64 + book[i] ) );
end;
procedure try(i: integer); {判第 断I 生分得优的优个学号}
var j: integer;
begin
j:=0;
repeat
j:=link[i,j]; { 取优表中喜优优优号j }
If not(j in flag) and (j>0) then
Begin
flag:= flag+ [j];
book[i]:=j;
if i=5 then print
else try(i + 1);
flag:= flag - [j]; {后退一步~以便优下一优分配方案找}
book[i]:=0;
End;
until j = 0;
end;
{ main prg }
begin
flag:= [];
c:=0;
try(1);
readln
end.
?1,2 深度优先搜索优例1
【例优2】 优子老鼠优迷优。优中有优影的部分表示优~无优影的部分表示通路。老鼠在迷优中可以沿上下左右
4方个向摸索前优。
?优一程序~由优算机自优到一上面入找条从条口优到下面出口优的一通道。?优优算
机优住路径当~第二次走
优~优能按路径从达优快入口到出口。
?优优分析,
(1)迷优的表示方法,迷优一般可以用一二优优个数A(Y~X)表示~其中~来Y表示行~X表示列。
数数优中的元素由字0和1优成。优的它含优是,
? 1 优
A(Y,X)=<
? 0 路
优迷优入口优的坐优优,(1~8)~迷优出口优的坐优优,(10~7)。
(2)搜索方向的优优,优于迷优中的任意一点A(Y~X)~有4搜索方个向,
A(Y-1~X)
?
A(Y,X-1) ? A(Y,X) ? A(Y,X+1)
?
A(Y+1~X)
(3)搜索方向的表示方法,我优优置一优坐优增量来描述优上下左右4搜索方个向
?(0~1)表示向右,(X增1)
?(-1~0)表示向上,(Y减1)
?(0~-1)表示向左,(X减1)
?(1~0)表示向下,(Y增1)
在程序中表示优~X方向增量优DX(I),Y方向增量优DY(I)~I的取优优1~2~3~4~表示4搜索方个向。优老鼠
向某个方向优探一步后的新坐优优表示优,
NX=X+DX(I) NY=NY+DY(I)
(4)向某个从方向搜索方法,上面的分析中看到~向某方向搜索前优一步的优
理~只需在当前位置坐优~加上
搜索方向的坐优增量DX(i)和DY(i)。 但修改位置坐优后一定要注意,任何一点的坐优加上要搜索方向的坐优增量
之后~都要判一下是否已断超出了迷优的优界。凡是X<0~或 x>10~或Y<0~或Y>10的情~况均表示新的位置坐优
已超出了迷优的优界。优优~就优放弃个向优方向搜索移优~改优向下一方向探索前优。
另况外~在不超出迷优优界的情下~如果A(Y~X)=0~优表示优方向有通路~可以优优向前走~若A(Y~X)=1~
优表示优方向是优~不能前行。
(5)优了防止老鼠在迷优中优入歧并当从条途在原地打优~老鼠某死胡同中退回优~优把优路堵死。要优优优
一点很容易~只需使A(Y~X)=2~已将即走优的路的优志优优死路优志可。
(6)优了能优住走出迷优的路径个将~在搜索优程中优要建立一堆优~老鼠走优的每一步路都优优下~来当老
鼠壁碰将从后退优~ 就退出的路堆优中优出去。优优~最优堆优中保存的就是走出迷优的一条通路了。优优优底
元素优迷优的入口优坐优~优优元素是迷优的出口优坐优。
优生式系优,
(1)据优。要存优数个老鼠在迷优中走优的路~那优每优优需要有,行、列坐优~搜索方向3据~根据以上个数
分析~据优优优成数数堆优形式~用优path表示~用优量并DEP作优优优指优~同优表示搜索的深度。
(2)优生优优。有8条数~若用优DX和DY表示各方向增量,
nx=x+dx(j)~ny=y+dy(j)
if (ny~nx)是通路then (ny~nx)是新优点
(3)搜索策略。采用深度优先搜索法~上优中优优的算法优行搜索。由于在即迷优探索路程优优~搜索深度优大~
用优优可能优生溢出~所以用非优优的深度优先算法。
程序如下,
program labyrinth(output)~
uses crt~
type node=record {定优存放行走路径的优优优型}
xx~yy,byte~ {位置坐优}
r,byte {搜索方向}
end~
a11=array[0..11~0..11] of byte~
const dx,array[1..4] of integer=(0~1~0~-1)~{X方向增量}
dy,array[1..4] of integer=(1~0~-1~0)~{Y方向增量}
a,a11=
((1,1,1,1,1,1,1,1,1,1,1,1),(1,0,0,0,0,0,0,1,0,1,1,1),
(1,0,1,0,1,1,0,0,0,0,0,1),(1,0,1,0,1,1,0,1,1,1,0,1),
(1,0,1,0,0,0,0,0,1,0,0,1),(1,0,1,1,1,1,1,1,1,1,1,1),
(1,0,0,0,1,0,1,0,0,0,0,1),(1,0,1,1,1,0,0,0,1,1,1,1),
(1,O,O,O,O,O,1,O,O,O,O,1),(1,1,1,O,1,1,1,1,0,1,O,1),
(1,1,1,1,1,1,1,1,0,1,1,1),(1,1,1,1,1,1,1,1,1,1,1,1));
{迷优布局~优了优程方便~在迷优的外面四周加了死路优优}
varb,all~
dep~j~k~x~y~xo~yo~nx~ny,integer~
path,array[0..300] of node~
p,boolean~
procedure wait~
begin for k,=1 to 5000 do end~procedure display(a,a11)~ {打印迷优布局}
var i~j,byte~
begin
fOr i,=0 to 11 do
begin
for j,=0 to 11 do write(a[i,j])~
writeln
end
end~
function check,bcxolean~{优优向某方向的探索前优是否成功}
begin
nx,=x+dx[j]~ {修改X方向坐优}
ny,=y+dy[j]~ {修改Y方向坐优}
if (nx<1) or (nx>11) or (ny<1) or (ny>11) {超出迷优优界}
then check:=false {check优假~表示此方向搜索前优失优}
else if a[ny,nx]>0 then check:=false {前方优优或死路}
else check:=true~ {此搜索方向可行}
end~
procedure backtrack; {回溯~返回上一步}
begin
repeat
dec(dep); {返回上一步~搜索深度将减1 }
if dep = 0
then t7: = true
else
hegin
a[y,x]: =2; {置死路优优}
gotoxy(x+1,y+1) ;write(chr(176)); {打印后退优优“圈”}
wait;
x:= path[dep].xx; {优优元素出优1}
y:= path[dep].yy;
j:= path[dep].r
end;
until (dep=O) or (j<4);
end;
procedure print(dep: integer);
var i, k: integer;
ch: char;
begin
gotoxy(nx + 1, ny + 1) ;write(chr(219) ); {打印行走成功优优“曰”}
gotoxy(1,15);
wri re( 'see you again(y/n) :'); readln(ch);
if (ch='y') or (ch='Y') then {重走迷优优优理}
begin
clrscr ;display(b); {打印迷优初始布局}
for i: = 1 to dep do
with path[i] do
begin gotoxy(xx + 1, yy + 1) ;write(chr(219) );
{根据优数Path中优优的行走路优~走出迷优路优}
wait;
end;
gotoxy(1,20); write( 'end !' ); readln
end;
halt
end;
{ ...... main prg .......... }
begin
y0: = 10; x0: =7; {迷优出口坐优}
b:=a; {保存迷优初始布局}
clrser;
display(a);
dep: = 1;
with path[1] do {初始化~优置迷优入口情况}
begin xx: =8;yy: = 1 end;
repeat
with path[dep] do
begin
x: =xx;y: =yy {取优优元素}
end;
gotoxy( x + 1, y + 1 ); write(chr(219) );
wait;
j: =0;p:=false;
repeat
inc(j); { 搜索前优方向}
if check then {某方向搜索前优成功 }
begin
a[y,x]:= 1; {将来路优优死路~避免老鼠在迷~优中原地打优}
path[dep], r: =j; {优优前优方向}
inc(dep);
with path[dep] do
begin
xx:= nx;yy:=ny; { 改坐优~前优一步}
end;
if (nx=x0) and (ny= y0) then print(dep) {达迷优出口}
else p: = true;
end
else
if j >= 4 then backtrack;
until p = true;
until dep=0;
readln
end.
想一想,上面优目中优定~老鼠在迷优中的行走方向优上下左右4方个向~如果将老鼠在迷优中可摸索前
优的方向优充优8个即~除了可以沿上下左右4方个向摸索前优外~优可以沿左上、右上、左下、右下4方个向
摸索前优~上述程序优如何修改~优同优自己优一优。 学
?1,2 深度优先搜索优例2
【例优3】 优士周游世界。在优国国象棋的棋优上~有一位优士按照优象棋中优的行走优优从棋优上的某一
方格出优~优始在棋优上周游。若能不重优地走遍棋优上的每一方个条格~优优的一周游路优在上
数学
数学高考答题卡模板高考数学答题卡模板三年级数学混合运算测试卷数学作业设计案例新人教版八年级上数学教学计划
称被
之优优国你个从个象棋优上优的哈密优优优。优优优一程序~优于优优优入的任意一起始方格的坐优~由优
算机自优优按如下找并国当从格式打印出优象棋优上优的哈密优优优。例如~优优坐优点(5~8)出优优~相优
的哈密优优优如下优所示,
?????????????????????????????????? 60 ? 11 ? 26 ? 29 ? 54 ? 13 ? 24 ? 21 ??????????????????????????????????? 27 ? 30 ? 61 ? 12 ? 25 ? 22 ? 51 ? 14 ??????????????????????????????????? 10 ? 59 ? 28 ? 55 ? 50 ? 53 ? 20 ? 23 ??????????????????????????????????? 31 ? 64 ? 57 ? 62 ? 43 ? 48 ? 15 ? 52 ??????????????????????????????????? 58 ? , ? 32 ? 49 ? 56 ? 19 ? 42 ? , ??????????????????????????????????? 33 ? , ? 63 ? 44 ? 47 ? 36 ? 39 ? 16 ??????????????????????????????????? , ? 45 ? , ? 35 ? 18 ? 41 ? , ? 37 ??????????????????????????????????? , ? 34 ? ! ? 46 ? , ? 38 ? 17 ? 40 ???????????????????????????????????优优分析,
(1)棋优的表示方法,我优用一个8X8的二优优数A(X~Y)表示优来国象棋的棋优。在优士没有优始周游棋
优优~棋优上所有的格中优数哪个将均置优零。以后~优士周游到一格~就其周游走优
的步优优在相优的数
空格中。
(2)棋优上优的跳优方向,如下优所示~在优国象棋优上~一匹优共有8个可能的跳优方向。
???????????
? ??? ??? ?
???????????
??? ? ? ???
???????????
? ? ?优? ? ?
???????????
??? ? ? ???
???????????
? ??? ??? ?
???????????
我优优置一优坐优增量来描述优8跳个优方向,
?(1~2) ?(2~1)
?(2~-1) ?(1~-2)
?(-1~-2) ?(-2~-1)
?(-2~1) ?(-1~2)
(3)优的跳优方向的表示方法,优I表示行~J表示列~每次跳优后~行增量优DI(r)~列增量优DJ(r)~
其中r=1~2~3~4~5~6~7~8表示优的8跳个即个优方向。优向某方向优探跳优一步后新的坐优表示优,
NI=I+DI(r) NJ=J+DJ(r)
(4)判优断个朝某方向优探性的跳优一步是否成功,如上所述~优跳优后新位置的坐优表示优原位置坐
优加上跳优方向的坐优增量。但每得到一个断新位置坐优后~都要判一下是否已超出了棋优的优界。 优于
例2中优优的优优~若 I<0~或I>8~或j<0~或,>8优~都表示已超出了棋优的优界~优优~优放弃向优方
向的跳优~优而优下一方个向优探。
在跳优不出界的情下~优要判此况断棋优格是否已优走优~如果A(NI~NJ)=0~表示此格未走优~优方
向搜索前优成功~可以优优向前跳优。若A(NI~NJ)>0~优表示优格已优走优了~不能再走。放优方弃并向
优向下一方个向优行优探。
思考优优,本优程序优同优自己出。学写
?1,3 深度优先搜索优优
【优优1】 优有一个4×4的棋优;即每行每列有4个正方形格,~用4格棋子布在格子中~要求优足以下件条:
A)任意2个棋子不在同一行和同一列上~
B)任意2个棋子不在同一优角优上~
优优有多少优棋局,优程把他优到打印出。找并来
【优优2】覆盖优优。 有优优优N;N优偶数)的正方形~优用你N2/2优优个2优优1的优方形~将它全部覆盖。
优程打印出所有覆盖方法。下面是当N,4优优几覆盖方法及打印格式,【优优3】液晶数字
?2 度优先搜索 广BFS
在深度优先搜索算法中~是深度越大的优点越先得到优展。如果在搜索中把算法改优按优点的优次优行
搜索~ 本优的优点有搜索优理完优~不能优下优优点优行优理~深度没即越小的优点越先得到优展~ 也就
是优先优生 的优点先得以优展优理~优优搜索算法优优度优先搜索法。称广英优中用 Breadth-First-Search
表示~所以我优 也把度优先搜索法优优广称BFS。
1、度优先搜索的广基本思想
优中从某一优点Vo出优~首先优优Vo相优的所有未被优优优的优点V1、V2、……Vt~再依次优优与V1、
V2、……Vt相优的且未被优优优的所有优点。如此优优~直到优优完优中所有的优点。
如果用度优先法优下优中优点优行搜索~优点广从V1出优~先搜索优理 的它子优点V2和V3~深度优即
2的优点~然后搜索深度优3的子优点V4、V5、V6、V7~最后搜索深度优 4 的优点V8和V9。整个搜索的次序
与优点优生的次序完全一致。
深度
__V1__ 1
/ \
V2 V3 2
/ \ / \
V4 V5 V6 V7 3
/ \
V8 V9 4
2.度优先搜索广基本算法,
1,某从个并号优点出优优始优优~被优优的优点作相优的优优~优出优优优点~
2,被从与并优优的优点出优~依次搜索优优点有优的优优的所有未被优优的优接点~作相优的优优。
3,再依次根据2,中所有被优优的优接点~优优优些优与接点相优的所有未被优优的优接点~直到所
有优点被优优优止。
【算法优程】
procedure guangdu(i);
begin
write(i);
v[i]:=true;
insert(q,i);{q是优列~i优优}
repeat
k:=delete(q)~{出优}
for j:=1 to n do
if (a[k,j]=1) and (not v[j]) then
begin
write(j);
v[j]:=true;
insert(q,j);
end;
until 优列q优空;
【优优优用】,优优优用的算法
流程
快递问题件怎么处理流程河南自建厂房流程下载关于规范招聘需求审批流程制作流程表下载邮件下载流程设计
优通常如下,
【优优描述】如下优~出找C1到C6的一条径并最短路求出其路程优优度(采用
广度优先搜索的优点优优
序列优C1,C2,C3,C4,C5,C6)。
【Pascal程序】
program tu3bfs;
type fg=set of 1..6;
const link:array[1..5,1..6] of integer=((0,4,8,0,0,0),
(4,0,3,4,6,0),(8,3,0,2,2,0),(0,4,2,0,4,9),(0,6,2,4,0,4));
var pnt,city:array[1..10] of 0..6;
flag:fg;
r,k,head,tail:integer;
procedure print;
var n, i,cost,y:integer;
s:array[1..7] of 1..6;
begin
y:=tail;n:=0; cost:=0;
while y>0 do begin inc(n);s[n]:=y;y:=pnt[y] end;
writeln('minpath=',n-1);
write('1');
for i:=n-1 downto 1 do
begin
write('->',s[i]);
cost:=cost+link[s[i+1],s[i]];
end;
writeln;
writeln('cost=',cost);
end;
begin
flag:=[1];
pnt[1]:=0; city[1]:=1;
head:=0;tail:=1;
repeat
head:=head+1;
k:=city[head];
for r:=2 to 6 do
if not(r in flag) and (link[k,r]>0) then
begin
inc(tail);city[tail]:=r;
pnt[tail]:=head;
flag:=flag+[r];
if r=6 then begin print;halt end;
end;
until head>=tail;
readln;
end.
?2,2 度优先搜索优例广
【例优】八数优优优(Eight-puzzle)。在3X3的棋优上~优有 8棋子个个~在每棋子上优有1,8中的某一字。数
棋优中留有一个空格。空格周优的棋子可以移到空格中。要求解的优优是~优出一优初始布局(初始状)和目优
优布局(目优优状)~到一优找从最少步优的移优方法~优优初始布局到目优布局的优优。初始状状优和目优优
如下,
初始状状优 目优优
2 8 3 1 2 3
1 6 4 8 4
7 5 7 6 5
求解本优我优可以分3步优行。
优优分析,
由于优目要的解是到目优的找达来最少步优~因此可以优优优优解优的方法,
初始状找达优优搜索的出优点~把移优一步后的布局全部到~优优是否有到目优的布局~如果有~再没从
优些移优一步的布局出优~出找两断达移优步后的所有布局~再判是否有到目优的。依此优推~一直到某布局
优目优优优状数从找止~优出优果。由于是按移优步少到多优生新布局的~所以到的第一目优一定是个移优步
数个最少的一~也就是最优解。
建立优生式系优,
(1)优合据优。用数3X3的二优优优表示数来棋优的布局比优直优。我优用Ch[i,j]表示第i行第j列格子上放
的棋子数字~空格优用0表示。优了优程方便~优来需存优下面3据,优个数布局的空格位置(Si~Sj)~初始布
局到优布局的步~深度数即dep~以及优布局的上一布局~即父优点的位置(pnt)。优优据优每一数个元素优优
是由上述据优成的优优。几个数
在程序中~定优优成据优数元素的优优型优,
Type
node,record
ch,array[1..3~1..3] of byte~{存放某优棋优布局}
si,sj:byte~ {优优此布局中空格位置}
dep,pnt,byte~
end~
因优新优生的优点深度(从数初始布局到优优点的步)一般要比数据优中原有的优点深度大(或相等)。按度广
优先搜索的算法~深度大(步多数)的优点后优展~所以新优生的优点优放在据优的后数面。而当从前优展的优点
数即广数据优前面优取~优理优是按优点优生的先后次序优行优展。优优度优先搜索的据优优构构采用优列的优
形式优合适。我优用优优优数data表示据优~优来数并两个置指优,Head优优列的首指优~tail优优列的尾指优。
(2)优生优优。原优优优定空格周优的棋子可以向空格移优。但如果优一优角度优察~也可看作空格向上、
下、左、右4位个置移优~优优优理更便于优程。优空格位置在(Si~sj)~优有4优优,条
?空格向上移优, if si-1>=1 then ch[si,sj]:=ch[si-1,sj]~ch[si-1,sj]:=0
?空格向下移优, if si+1<=3 then [si,sj]:=ch[si+1,sj]~ch[si+1,sj]:=0
?空格向左移优, if sj-1<=1 then [si,sj]:=ch[si,sj-1]~ch[si,sj-1]:=0
?空格向右移优, if sj+1<=3 then [si,sj]:=ch[si,sj+1]~ch[si,sj+1]:=0
我优用优数Di和Dj表示来移优优行列的增量~移优后新空格的位置可表示优,
nx:=si+di(r)
ny:=sj+dj(r)
其中~r=1,2,3,4优空格移优方向~且
r 1 2 3 4
方向 左 上 右 下
di 0 -1 0 1
dj -1 0 1 0
(3)搜索策略。按照优优分析中提出的方法~算法优优如下, program num8~
程序中新布局与优列中已有布局是否重优~用dup函数找优优~到目优优点后~print优程优优打印出从初始优到目优优
移优优各步的布局~buf[n)是用存放来待优出的布局在优列中的位置。procedure print~
根据上述算法优制的程序如下,
program num8_str1~
uses Crt~
type a33,array[1..3~1..3] Of byte~
{3X3的二优优~用于存放数棋优布局}
a4=array[1..4] of shortint;
node=record {定优据优中每数个构元素优优优型优}
ch: a33;
si, sj: byte;
pnt, dep: byte;
end;
const goal:a33 = ((1,2,3), (8,0,4), (7,6,5)); {目优布局}
start:a33 =((2,8,3), (1,6,4), (7,0,5)); {初始布局}
di:a4=(0,-1, 0, 1);
dj:a4=(-1, 0, 1, 0);
var data:array[1..100] of node;
temp: node;
r, k, ni, nj, Head, Tail, depth: integer;
{优量depth存放当前搜索深度}
function check(k: integer) :boolean; { 优优某步移优是否可行}begin
hi:=temp.si+di[k] ; nj:=temp.sj+dj[k];
if (ni in [1..3]) and (nj in [1..3]) {~移优后新位置仍在棋优中}
then check:=true else check:= false;
end;
function dupe: boolean; { 优优优尾新存入布局是否已在优列中存在}
var i,j, k: integer;
buf:boolean;
Begin
buf:= false; i: = 0;
{优量将i依次指向优列中的各个布局(最后一除个外)的位置}
repeat
inc(i) ;buf:= true;
for j:=1 to 3 do
for k:=1 to 3 do
if data[i].ch[j,k] < >data[tail].ch[j,k]
{data[tail]是优列中最后一个即元素~新优生的布局}
then bur:= false;
until buf or (i> = tail-1);
{buf=truee新布局与优列中布局有重优}
dupe:= buf
end;
function goals: boolean; { 比优是否到目优达状布局优}var i,j :byte;
begin
goals:= true;
for i:=1 to 3 do
for j:=1 to 3 do
if data[tail].ch[i,j] < >goa1[i,j]
then goals:=false {未到目优达布局}
end;
procedure trace;
var i,j :byte;
begin
write( 'cl=', Head,' op=', tail);
writeln('dep=',depth,'k=',k);
fori:=1 to 3 do
begin
for j:= 1 to 3 do write(data[tail], ch[i,j]);
writeln end;
end;
procedure print; {优出移优步优}
var buf: array[1..100] of integer;
{优数buf存放起始优、目优优以及起始从优到目优优所优优的各优的位置}
i,j, k, n: integer;
begin
n:= 1;
i:= tail;buf[1]:= i; {buf[1]中是目优布局在优列中位置}
repeat
j:=data[i].pnt; {data[I].pnt的优是布局I的父优点的位置}
inc(n); buf[n]:=j; i:=j
until i=0; {根优点(初优)的父优点优0~即I=0}
writeln(' staps:', depth + 1);
for i:= 1 to 3 do {打印棋优布局}
begin
for k:=n-1 down to 1 do
begin
for j:= 1 to 3 do write(data[buf[k]].ch[i,j]);
if i = 2 then write( ' - > ') else write(' ');
end;
writeln;
end;
readln; halt
end;
{ main program = }
begin
Head:= 0; tail:= 1;
with data[1] do {优列中存入第一个元素(初始状)}优
begin ch:= start; si:= 3; sj:= 2;
pnt:= 0; dep:= 0;
end;
repeat
inc(Head);temp:=data[Head]; {取优首优优}
depth:= temp.dep;
for r:= 1 to 4 do {优取出优优优行优展}
if check(r) then {布局中空格向某方向移优成功}
begin
inc(tail);data[tail]:= temp; {新优生布局存入优尾}
with data[tail] do
begin ch[si,si]:= ch[nj,nj];
ch[ni,nj]:=0;si:=nj;si:=nj;
pnt:=Head;{优优此布局的上一布局在优列中的位置}
dep:= depth + 1;{优优本布局的搜索深度}
end;
trace;
if dupe then dec(tail) {dec(tail优除新优生的优点)}
else if goals then print;
end;
until Head>=tail; {优列空}
writeln('no solution');readlnend
运行优果,
283 283 283 023 123 123
164>104>1—————84>184>084>804
705 765 765 765 765 765
上述程序优生的搜索各个布局优略。
上面搜索优中可看出~程序优行优先优生深度优从1的所有优点~然后再优生深度优2的所有优点……~最后
优生含有目优的深度优5的优点优束。先往向横广优展~再往优向深入~优就是度优先搜索法搜索优程。
上例我优看出~度优先搜索法可以求出步从广数即最少的解~深度最少的解。因此度优先搜索法优广常用于
一些求最优解的优优中。
深度优先搜索法优似~不同的优优用度优先搜索法的与广基本算法都是一优的~但在据优的表示方法上、数
在优生的优点是否符合件上和条断运重优的判上可以有不同的优程技巧~程序行效率也有所不同。以会数八优优
优优例~上面程序中用3X3的二优优表示数断断布局比优直优~但在判有重优布局~判是否到目优达布局方面~
却增加了优程优优性~同优也影响运来了行速度。我优可以改用字符串形式表示布局。
例如初始布局表示优
"283164705'’~目优布局表示优“123804765”~按行的优序排列。即
优生优优也必优作相优改优。优空格前当位置是Si~优有,
(1)空格向上移优,空格的位置减3~即交优Si和Si,3的字符~
(2)空格向左移优,空格的位置减1~即交优Si和Si,1的字符~
(3)空格向右移优,空格的位置加1~即交优Si和Si,1的字符~
(4)空格向下移优,空格的位置加3~即交优Si和Si,3的字符~
如优优优优优号k~优上述四优优可优优优一,条条
交优Si和Si+(2*k-5)的字符。
其中~k=1优向上移优~k=2优向左移优~k=3是向右移优~k=4优向下移优。
布局用字符串表示后~使得判断断两个重优和是否目优优优得十分优优~只需判
字符串是否相等就可以了。
【思考】优按照上述改优算法~优制出解八数优优的PASCAL程序。 ?2-3 双广向度优先搜索
广从找它度优先搜索遵循初始优点优始一优优优展直到到目优优点的搜索优优~只能优好地解优不是决状太多
的情~况很叙承受力有限。如果优展优点优多~而目优优点又优在优深优~采用前文述的度搜索解优~搜索广
量巨大是可想而知的~往往就出优存会内况双空优不优用的情。向搜索和A算法优广度优先的搜索方式优行了
改良或改造~ 加入了一定的“智能因素”~使搜索能快尽减接近目优优点~少了在空优和优优上的优优度。
(1)搜索优程
有些优优按照广既度优先搜索法优优展优点的优优~适合优序~也适合逆序~于是我优考优在优目优优点或找
路径—两的搜索优程中~初始优点向目优优点和目优优点向初始优点同优优行优展~直至在个优展方向上出优
同一个双个称子优点~搜索优束~优就是向搜索优程。出优的优同一子优点~我优优相交点~如果优存在一确
条从径双会初始优点到目优优点的最佳路~那优按向搜索优行搜索必然在某优出优“相交”~有相即交点~初
始优点一相交点一目优优点所形成的一条径即径路是所求路。
例如,移优一只个含字母A和B的字符串中的字母~优定初始状优优(a)表~目优状优优(b)表~优定移优优
优优,只能互相优优相优字母。优出一找条数移优最少步的优法。
[AABBAA] [BAAAAB]
(a) (b)
解优分析,从状状当达状初始优和目优优均按照深度优先搜索优展优点~到以下优优~出优相交点~如优1(a)~
优点序表示优点生成优序。号
双向优展优点,
优序 逆序
1 1
___AABBAA___ BAAAAB
2 / \ 3 2 / \ 3
__ABABAA__ AABABA ABAAAB BAAABA
4 / |5 \ 6 7 / \ 8 4 /
ABBAAA BAABAA ABAABA AAABBA AABAAB AABAAB
(a) 优1 (b)
优序优展的第8子个与优点逆序优展得到的第4个子优点就是相交点~优优的最佳路径如优2。
[AABBAA][AABABA][AABAAB][ABAAAB][BAAAAB]————
优2
搜索的优点看~从来双广个数向度要优优得多。假优每一子优点可以优展的子优点是X~不优优束件~条
以完全X叉优优算~那优用度优先搜索一优度优广个I的最佳路径的解~共需要优展优L-1)?(X-1)。从点X(XY双来个向搜索看~优正方向的搜索在第y优到找向交点~那优正向共搜索了 X(X-1)?(X-1)~逆向优展的优LYL点优数(X-y-1)?(X-1)~方两个向共搜索了 X(X+X-Y-2)?(X-1)。我优假优L优偶数~优Y=L/2~双向搜索L/2L/2优展的优点优优优数向搜索的2?(X+1)*100,~相优少减(X-L/21)?(X+1)*100,。
然优当个它况双里只是作粗略的比优~事优上在其一般情下~向搜索搜索量都要比优向搜索的少。 来
(2)优点优展优序
双两个向优展优点~在方向的优展优序上~可以优流交替优行~但由于大部分的解答优不是完全优~并棵
在优展完一优后~下一优优优优优点优少的那方个数个两个向先优展~可以克服方向优点生成速度不平衡的状
优~明优提高搜索效率。
(3)据优数构
优向广两个度优先搜索需建立表OPEN和CLOSED~用存优生成优点和已优来展优点~双从两个向搜索方向优
行优展~我优建立二优表 两个OPEN~CLOSED~OPEN[1]~CLOSED[1]~ OPEN[2]~CLOSED[2]分优存优方两个向
上的生成优点和已优展优点~OPEN仍然是具有“先优先出”的优列优。优优程方便构~我优采用基于度优先广
搜索算法的双个向~建立三二优指优,Q1~Q2~Q3其作用如下,
Q1[1]~Q1[2],分优指向两个当个方向上前待优展优的第一优点。
Q2[1]~Q2[2],分优指两个方向上优尾新优生的优点。
Q3[1]~Q3[2],分优指向两个个方向上下一优的第一优点位置。
优了分区当前搜索方向~优方向优志,
t=1表示优于正向搜索~t=2表示优于逆向搜索。
Fail—有一方个真并向搜索失优优~优~且优束搜索优程~否优优假。
I—全局优量~指向前当要优展的优点。
(4)算法描述
Program DOUBFS~
初始化~初始优点~和目优优点分优优入OPEN[1]和OPEN[2]表~
Q1[1]:=1;Q2[1]:=1;Q1[2]:=1;Q2[2]:=1~
repeat
if (Q2[1]-Q1[1])<=(Q2[2]-Q1[2]) then t:=1
else t:=2~
for I:=Q1[t] to Q2[t] do
EXPEND(t)~{优展第1优点个}
Q1[t]:=Q3[t]~
until(Q1[t]>Q2[t])~
其中优程EXPEND(t)的优如下,构
Procedure expand(t,integer)~
Var j,integer~
begin
for j:=1 to n do {n优最多后优优优状数}
begin
优生i点的第j后优优~加入到优个状将它尾(Q2[t]+1)~
if新优点未其上一优以上的所有点与重优
then if isans(t) then [优出解~halt~] else
else将从新点优列中去掉~(Q2[t]-1)
end~ -
end~
判是否是相断交点的优程isans(t)如下,
function isans(t,integer),Boolean~
var j~t1,integer~
begin
if t=1 then t1:=2 else t1:=1~
isans:=false~
forj:=Q1[t1] to Q2[t1] do
if Q2[t]=j {Q2[t]新优点是相交点}
then [isans:=true~exit]~
end~
(5)例优优用
【例1】魔方优优
在魔方优靡全球之后~Rubik先生优明了的优它——化版魔板。魔板由8个同优大小的方优优成~每方优个
的优色均不相同~本优中以字数1—8分优表示~可能出优在魔板的任一位置~任一优刻魔板的优可以用方优状
的优色序列表示,从写号魔板的左上角优始~按优优优方向依次下各方优的优色代~得到的字序列可表示数即
此优魔板的优。状
例如~序列(1~2~3~4~5~6~7~8)表示优中魔板的初始状优。
1 2 3 4
8 7 6 5
优于魔板~可以施加三优不同的操作~分优以A~B~C优优。
具体操作方法如下,
A,上下行互优~如上优可以优优优优状87654321
B,每行同优循优右移一格~如上优可以优优优41236785
C,中优4方优优优优个旋优一格~上优可以优优优17245368。
优用优三优基本操作~可以由任一优到状达另状任意一优优。
子任优A,
优优一程序~优于优入的一目优优~优一优个状找从状操作的序列~使得初始优优始~优优此操作序列后
使优魔板优优目优优。状
子任优B,
如果的程序优到的你找操作序列在300步以~得到内会子任优B的分。数
优入据,数
文件名INPUT,TXT~第一行包含8个个数以一空格相隔的正整~表示目优
状优。
优出据,数
优出文件名优OUTPUT,TXT~在第一行优出的程序优到的你找操作序列的步
数L~后随L行是相优的操作序列
~每行的行首写个一字符~代表相优的操作。
【算法分析】n。A,空优优优度 如果解的步优数n~优优表示状空优优占3
B,基本算法 本优是典型的度优先算法优~自然的想到能否广很构启造优算法。但
本优不同于八数很找优~优优到
一个估数状达状价函。因优每一优优的到都有三优本优不同的方法~因此在优算某一优
的估将状价优优~容易优
各字的个数数构个当数最少移优步重优优算~或忽略优算~不能优造出一恰函f*~使
得f*< f。因此不宜采用优启
算法得出最优解~而只能得可行解。优在考优双广向度优先搜索。双与广向搜索优向度搜索相比的优点在于优省了存优空优~避免搜索出更多的无用优
点~提高丁搜索速度~如果
采用优优优存优数(655 350Byte)可以做到大优21,22步~甚至可以更多。
【考程序】 参
Program Rubic~
Uses Crt;
Const
n=8;
input = 'input.txt';
Type
dar = record
f: integer;
d: array[1..n] of Integer;
End;
Var
Cab: array[1..2,1..7500] of ^dat;
dat1,dat2: dat;
Procedure Init;
Var
f: text;
i,i: Integer;
Begin
assign(f, input);
reset(f);
new(cab[1,1]);
for I:=1 To n do
read(f,cab[1,I]^.d[i]);
cab[1,1]^.f := 0;
readln(f);
new(cab[2,1 ] );
for I := 1 tondo
read(f,cab[2,1]^.d[i]);
readln(f);
cab[2,1]^.f := 0;
End;
Function Check(x,y: Integer) :boolean;
Var
i,j,k: Integer;
ok: Boolean;
Begin
for i:= 1 to y-1 do
Begin
forj := 1 to n do
if cab[x,i]^.d[j] < > dat1.d[j] then
Begin
ok := true;
Break;
End else Ok:= false;
if not ok then break;
End;
Check := ok;
End;
Function CheckOut(X,Y: Integer;Var a: Integer): Boolean;
Var
i,j,k: Integer;
ok: Boolean;
Begin
a:=0;
fori := 1 to y do
Begin
for j := 1 to n do
if cab[x,i]A.d[j] < > dat1.d[j] then
Begin
ok := true;
Break;
End else Ok: = false;
if not ok then
Begin
a:= i;
break;
End;
End;
CheckOut := ok;
End;
Procedure Print(a,b,c: Integer);Var
i,j,k,l: Integer;
s1,s2: array[1..30] of Integer;
x,y: Integer;
Begin
fillchar(s1,sizeof(s1), 0);
fillchar(s2,sizeof(s2) ,0);
if a = 1 then
Begin
i:=1;
j:=2;
End else
Begin
i:=2;
j:=1;
End;
k:= O;
Repeat
inc(k);
s1[k] := b;
b := cab[i,b]^.f;
Until b = 0;
l:= 0;
Repeat
inc(l);
s2[l] := c;
c := cab[j,c]^.f;
Until c = 0;
if a = 1 then
begin
for x := k downto 1 do
Begin
for y := 1 to n do
write(cab[1,s1[x]]^.d[y]: 3);
if y mod 4 = 0 then writeln;
End;
writeln('-----');
Readln;
End;
for x := 2 to l do
Begin
for y := 1 to n do
Begin
write(cab[2,s2[x]]^.d[y]: 3);
if y mod 4 = 0 then writdn;
End;
writeln('-----');
Readln;
End;
End
else
Begin
for x := l downto 1 do
Begin
for y := 1 to n do
write(cah[1,s2[x]]^.d[y]: 3);
if y mod 4 = 0 then writdn;
End;
writeln('-----');
Readln;
End;
for x := 2 to k do
Begin
for y:= 1 to n do
begin
write(cab[2,s1[x]]^.d[y]: 3);
if y mod 4 = 0 then writeln;
End;
writeln('-----');
Readln;
End;
End;
Halt;
End;
Procedure Double;Var
i,j: array[1..2] of Integer;
Out: Boolean;
k,l,kk,s: Integer;
i[1] := 1;
i[2] := 1;
j[1] := 2;
j[2] := 2;
Out := false;
repeat
kk:=2;
k:=1;
{--1--}
dat1.d := Cab[k,i[k]]^.d;
for l := 1 to 4 do
Begin
dat1.d[l] := dat1.d[l+4];
dat1.d[l+4] := cab[k,i[k]]^.d[l];
End;
dat1.f := i[k];
if Check(k,j[k]) then
Begin
new(mb[kd[k]]);
mb[kd[k]]^:= dat1;
inc(j[k]);
if Not CheckOut(kk,j[kk] - 1,s) then Print(k,j[k] - 1 ,s);
End;
{--2--}
dat1.d := Cab[k,i[k]]^.d;
dat1.d[3]: = dat1.d[2];dat1.d[2] := dat1.d[5];dat1.d[5] := dat1.d[6];dat1.d[6] := cab[k,i[k]]^.d[3];
dat1.f: = i[k];
if Check(k,j[k]) then
Begin
new(cab[k,j[k]]);
cab[k,j[k]]^ := dat1;
inc(j[k]);
if NOt CheckOut(kk,j[kk] - 1,s) then Print(k,j[k] - 1,s);
End;
{--3--}
dat1.d:= Cab[k,i[k] ]^.d;
dat1.d[4]: = dat1.d[3];dat1.d[3]: = dat1.dj2];dat1.d[2] := dat1.d[1];dat1.dj1] := cab[k,i[k]]^.d[4];
dat1.f := i[k];
if Check(k,j[k]) then
Begin
new(cab[k,j[k]]);
cab[k,j[k]]^:= dat1;
inc(j[k]);
if Not CheckOut(kk,j[kk]- 1,s) then Print(k,j[k] - 1,s);
End;
Inc(i[k]);
kk:= 1;
k:=2;
{--1--}
dat1.d := Cab[k,i[k]]^.d;
for l := 1 to 4 do
Begin
dat1.d[l] := dat1.d[l+4];
dat1.d[l+4] := cab[k,i[k]]^.d[l];
End;
dat1.f:= i[k];
if Check(k,j[k]) then
Begin
new(cab[k,j[k] ]);
cab[k,j[k]]^:= dat1;
inc(j[k]);
if Not CheckOut(kk,j[kk] - 1 ,s) then Print(k,j[k] - 1 ,s);
End;
{--2--}
dat1.d := Cab[k,i[k]]^.d;
daft. d[2] : = dat1. d[3];
dat1.d[3] := dat1.d[6];
dat1.d[6]: = dat1.d[5];
dat1.d[5] := cab[k,i[k]]^.d[2];
dat1.f: = i[k];
if Check(k,j[k]) then
Begin
new(cab[k,j[k]]);
cab[k,j[k]]^:= dat1;
ine(j[k]);
if Not CheckOut(kk,j[kk] - 1 ,s) then Print(k,j[k] - 1 ,s);
End;
{---3---}
dad.d:= Cab[k,i[k]]^.d;
dat1.d[1] := dat1.d[2];
dat1.d[2] := dat1.d[3];
dat1.d[3] := dat1. d[4];
dat1.dj4] := cab[k,i[k] ]^.d[1];
dat1.f := i[k];
if Check(k,j[k]) then
Begin
new(cab[k,j[k]]);
cab[k,j[k]]^ := dat1;
inc(j[k]);
if Not CheckOut(kk,j[kk] - 1,s) then Prim(k,j[k] - 1,s);
End;
Inc(i[k]);
until Out;
End;
Begin
INit;
clrscr;
Double;
End,
?2-4 度优先搜索优优优广
很多优优都可以用广度优先搜索优行优理~如优优优翻(优优优参策略中的移优棋子优优)、最短路径参优优;优优优
优划,等。
1,用字符串的方式‘283164705’-> '123804765'优理8数优优优。2,优子老鼠优迷优。如下优12×12方格优~出一自入找条口;2~9,到出口;11~8,的最短路径。
3,如下优,求优中被*优成的封优区个数域的面优;方格的不包括*所在的方格,。
**
* *
* *
*** *
* *
* ***
* *
* *****
* *
***
4)分酒优优,有一酒瓶装有8斤酒~有量没装器~只有分优5斤和3斤的空酒瓶将。优优一程序8斤
酒分成两个4斤~以并最少的步优优出答案。
5)移优棋子游优,在下列所示的10个两格子里~前面格是空格~后面相优的放着4个A和4个B
ABABABAB
若每次可移优任意相优的两个两来将棋子优入空格~移优优棋子不得更优其原次序目优是4个A优在一起~空格位置不限。优优程~求出一优
方案优出每并状移优一次后得棋子优。