常用算法及策略(递归)
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
5 若限定第一个皇后 必须放在第1行上, 6 则仅需判定所放置的 7 诸皇后是否在同一列 8
已经对角线位置上.
编写试放置下一个皇后的递归过程:
Procedure 试放置下一个皇后;{带参过程} begin 为选择下一个皇后的位置设置初始状态; repeat 选择下一个位置,即下一列; if 可接受 then begin 放置皇后; if 未放置完8个皇后 then begin 试放置一个皇后;{递归调用,但参数不同} if 放置不成功 then 移去皇后 end else 置放置成功标志; end; until (放置成功) or (位置试完); end;
应用递归算法求解问题有两个特点: (1)存在某个特定条件,在这个特定条件下,可得到指定的解, 即递归存在终止状态;
(2)对任意给定的条件,有明确的定义规则,可以产生新的状态, 并将最终导出终止状态,即存在导致问题求解的递归步骤。
二、递归过程和函数 递归过程和一般过程的设计不同:
一般过程明确提出要计算机每步怎样去做;
二、探索策略和回溯算法 递归技术的一个重要应用是在人工智能领域中用递归形式来 表示探索策略或者说控制策略的回溯算法过程。
回溯过程是一种控制策略可以试探的方法,按照一定的规则, 不断试探,不断纠错,直到找到问题的解,或确信不存在为止。
为求解一个特定问题,一般应执行如下三个步骤: (1)定义问题,包括待解问题的初始状态及目标状态; (2)分析问题,寻找对求解问题能起重要作用的一些特征; (3)选择合适技术去求解问题。
对于不要求大量试探的问题,采用回溯法比较适宜而且效率较高。
〔例5-18〕求解八皇后问题。 把八个皇后摆在8*8国际象棋盘格子内,使它们互不捕获对方。 即在任何一行、一列或一条对角线上,仅能放置一个皇后。 八皇后问题有解, 1 2 3 4 5 6 7 8 并且解不唯一. 1 共有92组不同的解. 如右是一组解. 2 八个皇后中的每一个 3 皇后必定位于不同的 4 行和不同的列上.
可接受的条件:a[j] and b[I+j] and c[I-j]
5、放置皇后:若定义一整型数组x var x:array[1..8] of integer; 以x[1]表示第1行上的皇后所在位置,即x中存放解的布局。 放置皇后可表示:x[i]:=j; a[j]:=false; b[I+j]:=false; c[I-j]:=false; 6、未放置完8个皇后:I<8; 7、试放置一个皇后:try(I+1,q); 8、放置不成功: not q; 9、移去皇后:a[j]:=true;b[I+j]:=true;c[I-j]:=true;
10、放置成功标志:q:=true; 11、放置成功 or 位置试完:q or (j=8)
相关练习:
• • • • • • • 用递归的方法完成下列问题 1.求数组中的最大数 2.1+2+3+...+n 3.求n个整数的积 4.求n个整数的平均值 5.求n个自然数的最大公约数与最小公倍数 6.有一对雌雄兔,每两个月就繁殖雌雄各一对兔 子.问n个月后共有多少对兔子?7.已知:数列 1,1,2,4,7,13,24,44,...求数列的第 n项.
分析: 1、将A柱中位于上面的几个圆盘视作整体,暂将它们移动B柱上; 2、将A柱剩下的那个最大圆盘移到C柱; 3、将B柱那几个圆盘视作整体移到C柱。
如下图:n=3 移动:A—C A—B
C—B A—C B—A B—C A—C
ห้องสมุดไป่ตู้
A
B
C
算法分析:
移塔的过程:MoveTower(N,A,C,B); MoveTower(N-1,A,B,C); (0,1,2,3) 分解: 和把一个圆盘从A柱移到C柱。 MoveTower(N-1, B, C, A); (1,1,3,2) 1—3 (0,2,3,1) (2,1,2,3) 1—2 (0,2,3,1) n=3 3—2 (1,2,3,1) (0,1,2,3) (3,1,3,2) 1—3 (0,2,3,1) (1,2,1,3) 2—1 (0,3,1,2) (2,2,3,1) 2—3 (0,2,3,1) (1,1,3,2) 1—3 (0,2,3,1)
begin writeln('inter'); continue:='Y'; while continue='Y' do begin i:=0; write('number:'); readln(n); writeln('moving:'); move(n,1,3,2); writeln; write('continue?---'); readln(continue); continue:=upcase(continue) end; writeln('ok,good bye'); end.
4、可接受,说明若在第i和第j列放置皇后,则在第j列上没有 皇后,与i行j列交叉的也没有皇后。 a:array[1..8]of boolean; {第j列上无皇后标志} b:array[b1..b2]of boolean;{从右上到左下对角线无皇后标志} c:array[c1..c2]of boolean;{从左上到右下对角线无皇后标志} 右上到左下满足:行坐标+列坐标=i+j;(常数) 左上到右下满足:行坐标+列坐标=i-j;(常数)
program p32; 写出下列程序的运行结果: var a,b:array[1..32] of integer; I:integer; Begin Procedure ssort(I,j:integer); For I:=1 to 16 do a[i]:=I; Var m,k,x:integer; Ssort(1,16); Begin For I:=1 to 16 do write(a[i]:3); If j-I>1 then Writeln; Begin Readln; M:=( I+j ) div 2; End. Ssort( I,m ) ; Ssort( m+1,j ); K:=I; 1 9 5 13 3 11 7 15 2 10 6 14 4 12 8 16 For x:=I to m do Begin B[k]:=a[x]; B[k+1]:=a[m+x-I+1]; K:=k+2; End; For x:=I to j do A[x]:=b[x]; End; End;
program ex5_15; var n:1..64; continue:char; i:integer; procedure dise(fd,td:integer) ; begin i:=i+1; writeln(fd:2,'---->',td:2,' '); if i mod 10 =0 then writeln end; procedure move(n,a,c,b:integer); begin if n>0 then begin move(n-1 ,a,b,c); dise(a,c); move(n-1,b,c,a); end;
1、过程首部,过程名为try,其首部形式入下 procedure try(I:integer;var q:boolean); I为所放置下一个皇后的行号,亦表示是第几个皇后; q为放置成功的标志。
2、为选择下一个皇后的位置,设置初始状态:每次均从第1列 开始探索,j代表列号,即j:=0;
3、选择下一位置,即下一列:j:=j+1; q:=false;前假设为不成功。
[例5-16]把一个十进制整数转化为k进制(k<=10) 根据进制转化的规则,把一个十进制整转化为k进制数,只要 用k依次去除这个数及其商,所得的余数依次作为k进制数相继 的低位数字。依此,直至商为0为止。最后的余数作为k进制数 的最高位数字。 算法如下:
(1)digit:=number mod k; (2)number:=number div k; (3)判number是否为0; (4)如果number不为0,则调用tentok(number,ok); (5)否则输出digit。
〔例5-14〕已知正整数n,n的阶乘定义如下: 1 若n=0 N!= Number=6 n*(n-1)! 若n>0 Program ex5_14; 0 f(6) Var number,fact:longint; 1 6*f(5) Function f(n:integer):longint; 2 5*f(4) Begin 4*f(3) if n<0 then writeln(‘input error!’) 3 4 3*f(2) else if n=0 then f:=1 5 2*f(1) else f:=n*f(n-1); 6 1*f(0) End; Begin write(‘input n:’); readln(number); fact:=f(number); wtieln(fact); readln; End.
二、递归
递归是计算机科学的一个重要概念,递归的方法是程序设计中 有效的方法,采用递归编写程序能是程序变得简洁和清晰.
一、 什么是递归
1.概念 一个过程(或函数)直接或间接调用自己本身,这种过程(或函数) 叫递归过程(或函数). 如,数学上所有的正偶数的集合可递归定义为: (1)0是一个偶数; (2)一个偶数和2的和是一个偶数。
递归过程只描述递归关系和终止条件(就象递归算法自身的描述), 具体的执行过程并不明显指出,它被隐含在系统对递归的处理中。
〔例5-15〕汉诺(Hanoi)塔问题。 设有n个大小不等的中空圆盘,按照从小到大的顺序叠套在 立柱A上。另有两根立柱B和C,问题要求把全部圆盘从A柱(源柱 移到C(目标柱),移到过程中可借助B助(中间柱)。 移动有如下要求: (1)一次只移动一个盘; (2)不允许把大盘放在小盘上边; (3)可使用任意一根力柱暂存圆盘。