搜索与回溯算法C学习教案.pptx
《搜索与回溯算法C学习教案.pptx》由会员分享,可在线阅读,更多相关《搜索与回溯算法C学习教案.pptx(45页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、会计学1搜索搜索(susu)与回溯算法与回溯算法C第一页,共45页。递归回溯法算法框架递归回溯法算法框架 一一intSearch(intk)for(i=1;i=算符种数算符种数;i+)if(满足条件满足条件)保存结果保存结果(jigu)if(到目的地到目的地)输出解输出解;elseSearch(k+1);恢复:保存结果恢复:保存结果(jigu)之前的状态之前的状态回溯一步回溯一步递归回溯法算法框架递归回溯法算法框架 二二intSearch(intk)if(到目的地到目的地)输出解输出解;elsefor(i=1;i=算符种数算符种数;i+)if(满足条件满足条件)保存结果保存结果(jigu);S
2、earch(k+1);恢复:保存结果恢复:保存结果(jigu)之前的状态之前的状态回溯一步回溯一步第2页/共45页第二页,共45页。【例【例1】素数环】素数环:从从1到到20这这20个数摆成一个环,要求相邻的两个数的和是一个素个数摆成一个环,要求相邻的两个数的和是一个素数。数。【算法分析】【算法分析】非常明显,这是一道回溯的题目。从非常明显,这是一道回溯的题目。从1开始,每个空位有开始,每个空位有20种可能,只要填进去种可能,只要填进去的数合法:与前面的数不相同;与左边相邻的数的和是一个素数。第的数合法:与前面的数不相同;与左边相邻的数的和是一个素数。第20个数还个数还要判断和第要判断和第1个
3、数的和是否个数的和是否(shfu)素数。素数。【算法流程】【算法流程】1、数据初始化;、数据初始化;2、递归填数:判断第、递归填数:判断第i个数填入是否个数填入是否(shfu)合法;合法;A、如果合法:填数;判断是否、如果合法:填数;判断是否(shfu)到达目标(到达目标(20个已填完):是,打印结个已填完):是,打印结果;不是,递归填下一个;果;不是,递归填下一个;B、如果不合法:选择下一种可能;、如果不合法:选择下一种可能;【参考程序】【参考程序】#include#include#include#includeusingnamespacestd;boolb21=0;inttotal=0,a
4、21=0;intsearch(int);/回溯过程回溯过程intprint();/输出方案输出方案boolpd(int,int);/判断素数判断素数第3页/共45页第三页,共45页。intmain()search(1);couttotalendl;/输出总方案数输出总方案数system(pause);intsearch(intt)inti;for(i=1;i=20;i+)/有有20个数可选个数可选if(pd(at-1,i)&(!bi)/判断与前一个判断与前一个(y)数是否构成素数及该数是否可用数是否构成素数及该数是否可用at=i;bi=1;if(t=20)if(pd(a20,a1)print(
5、);elsesearch(t+1);bi=0;intprint()total+;couttotal;for(intj=1;j=20;j+)coutaj;coutendl;boolpd(intx,inty)intk=2,i=x+y;while(ksqrt(i)return1;elsereturn0;第4页/共45页第四页,共45页。【例【例2】设有】设有n个整数的集合个整数的集合1,2,n,从中取出任意,从中取出任意(rny)r个数进行排列个数进行排列(rn),试列出所有的排列。),试列出所有的排列。#include#include#includeusingnamespacestd;intnum
6、=0,a10001=0,n,r;boolb10001=0;intsearch(int);/回溯过程回溯过程intprint();/输出方案输出方案intmain()coutnr;search(1);coutnumber=numendl;/输出方案总数输出方案总数第5页/共45页第五页,共45页。int search(int k)int i;for(i=1;i=n;i+)if (!bi)/判断i是否(sh fu)可用 ak=i;/保存结果 bi=1;if(k=r)print();else search(k+1);bi=0;int print()num+;for(int i=1;i=r;i+)co
7、utsetw(3)ai;coutendl;第6页/共45页第六页,共45页。【例【例3】任何一个】任何一个(y)大于大于1的自然数的自然数n,总可以拆分成若干个小,总可以拆分成若干个小于于n的自然数之和。的自然数之和。当当n=7共共14种拆分方法:种拆分方法:7=1+1+1+1+1+1+17=1+1+1+1+1+27=1+1+1+1+37=1+1+1+2+27=1+1+1+47=1+1+2+37=1+1+57=1+2+2+27=1+2+47=1+3+37=1+67=2+2+37=2+57=3+4total=14第7页/共45页第七页,共45页。【参考程序】【参考程序】#include#incl
8、ude#includeusingnamespacestd;inta10001=1,n,total;intsearch(int,int);intprint(int);intmain()cinn;search(n,1);/将要拆分的数将要拆分的数n传递给传递给scouttotal=totalendl;/输出输出(shch)拆分的方案数拆分的方案数system(pause);intsearch(ints,intt)inti;for(i=at-1;i=s;i+)if(i0时,继续递归 s+=i;/回溯:加上拆分的数,以便产分所有可能的拆分 int print(int t)coutn=;for(int
9、i=1;i=t-1;i+)/输出一种拆分方案 coutai+;coutatendl;total+;/方案数累加1第8页/共45页第八页,共45页。【例【例4】八皇后问题:要在国际象棋棋盘中放八个皇后,使任意两个皇后】八皇后问题:要在国际象棋棋盘中放八个皇后,使任意两个皇后都不能互相吃。(提示:皇后能吃同一行、同一列、同一对角线的任意都不能互相吃。(提示:皇后能吃同一行、同一列、同一对角线的任意棋子棋子(qz)。)。)放置第个放置第个(行行)皇后的算法为:皇后的算法为:intsearch(i);intj;for(第第i个皇后的位置个皇后的位置j=1;j=8;j+)/在本行的在本行的8列中去试列中
10、去试if(本行本列允许放置皇后本行本列允许放置皇后)放置第放置第i个皇后;个皇后;对放置皇后的位置进行标记;对放置皇后的位置进行标记;if(i=8)输出输出/已经放完个皇后已经放完个皇后elsesearch(i+1);/放置第放置第i+1个皇后个皇后对放置皇后的位置释放标记,尝试下一个位置是否可行;对放置皇后的位置释放标记,尝试下一个位置是否可行;第9页/共45页第九页,共45页。【算法分析【算法分析(fnx)】显然问题的关键在于如何判定某个皇后所在的行、列、斜线上是否有别的皇后;显然问题的关键在于如何判定某个皇后所在的行、列、斜线上是否有别的皇后;可以从矩阵的特点上找到规律,如果在同一行,则
11、行号相同;如果在同一列上,则列可以从矩阵的特点上找到规律,如果在同一行,则行号相同;如果在同一列上,则列号相同;如果同在号相同;如果同在斜线上的行列值之和相同;如果同在斜线上的行列值之和相同;如果同在斜线上的行列值之差相斜线上的行列值之差相同;从下图可验证:同;从下图可验证:考虑每行有且仅有一个皇后,设一维数组1.8表示皇后的放置(fngzh):第行皇后放在第列,用ij来表示,即下标是行数,内容是列数。例如:A3=5就表示第3个皇后在第3行第5列上。第10页/共45页第十页,共45页。判断皇后是否(sh fu)安全,即检查同一列、同一对角线是否(sh fu)已有皇后,建立标志数组1.8控制同一
12、列只能有一个皇后,若两皇后在同一对角线上,则其行列坐标之和或行列坐标之差相等,故亦可建立标志数组1.16、-7.7控制同一对角线上只能有一个皇后。如果斜线不分方向,则同一斜线上两皇后的行号之差的绝对值与列号之差的绝对值相同。在这种方式下,要表示两个皇后I和J不在同一列或斜线上的条件可以描述为:AIAJ AND ABS(I-J)ABS(AI-AJ)I和J分别表示两个皇后的行号【参考程序】#include#include#include#includeusing namespace std;bool d100=0,b100=0,c100=0;int sum=0,a100;int search(in
13、t);int print();int main()search(1);/从第1个皇后开始放置 system(pause);第11页/共45页第十一页,共45页。int search(int i)int j;for(j=1;j=8;j+)/每个皇后都有8位置(列)可以试放if(!bj)&(!ci+j)&(!di-j+7)/寻找放置皇后的位置 /由于C+不能操作负数组,因此考虑(kol)加7 /放置皇后,建立相应标志值 ai=j;/摆放皇后 bj=1;/宣布占领第j列 ci+j=1;/占领两个对角线 di-j+7=1;if(i=8)print();/个皇后都放置好,输出 else search(i
14、+1);/继续递归放置下一个皇后 bj=0;/递归返回即为回溯一步,当前皇后退出 ci+j=0;di-j+7=0;int print()int i;sum+;/方案数累加1 coutsum=sumendl;for(i=1;i=8;i+)/输出一种方案 coutsetw(4)ai;cout2,1-3,3-1,4-3,5-2,7-4,8【算法分析】【算法分析】如图如图4(b),马最多有四个方向,若原来的横坐标为马最多有四个方向,若原来的横坐标为j、纵坐标为、纵坐标为i,则四个方则四个方向的移动可表示为:向的移动可表示为:1:(i,j)(i+2,j+1););(i3,j8)2:(i,j)(i+1,j
15、+2););(i4,j0,j1,j8)搜索搜索(susu)策略:策略:S1:=(0,0);S2:从从1出发,按移动规则依次选定某个方向,如果达到的是(出发,按移动规则依次选定某个方向,如果达到的是(4,8)则)则转向转向S3,否则继续搜索否则继续搜索(susu)下一个到达的顶点;下一个到达的顶点;S3:打印路径。打印路径。第13页/共45页第十三页,共45页。【参考程序】【参考程序】#include#include#includeusingnamespacestd;inta100100,t=0;/路径总数和路径路径总数和路径intx4=2,1,-1,-2,/四种移动规则四种移动规则y4=1,2
16、,2,1;intsearch(int);/搜索搜索(susu)intprint(int);/打印打印intmain()/主程序主程序a11=0;a12=0;/从坐标从坐标(0,0)开始往右跳第二步开始往右跳第二步search(2);system(pause);第14页/共45页第十四页,共45页。int search(int i)for(int j=0;j=0&ai-11+xj=0&ai-12+yj=8)/判断马不越界 ai1=ai-11+xj;/保存当前(dngqin)马的位置 ai2=ai-12+yj;if(ai1=4&ai2=8)print(i);else search(i+1);/搜索
17、下一步 int print(int ii)t+;coutt:;for(int i=1;i=ii-1;i+)coutai1,ai2;cout4,8endl;第15页/共45页第十五页,共45页。【例【例6】设有】设有A,B,C,D,E五人从事五人从事J1,J2,J3,J4,J5五项工作,每人只五项工作,每人只能能(zhnn)从事一项,他们的效益如下。从事一项,他们的效益如下。每人选择五项工作中的一项,在各种选择的组合中,找到效益(xioy)最高的的一种组合输出。【算法分析】【算法分析】用数组储存工作选择用数组储存工作选择(xunz)的方案;数组存放最优的工作选择的方案;数组存放最优的工作选择(x
18、unz)方案;数组用于表示某项工作有没有被选择方案;数组用于表示某项工作有没有被选择(xunz)了。了。(1)选择选择(xunz)(i)=0的第的第i项工作;项工作;(2)判断效益是否高于判断效益是否高于max已记录的效益,若高于则更新数组及已记录的效益,若高于则更新数组及max的值。的值。搜索策略搜索策略:回溯法(深度优先搜索回溯法(深度优先搜索dfs)。)。第16页/共45页第十六页,共45页。【参考程序】【参考程序】#include#include#include#includeusingnamespacestd;intdata66=0,0,0,0,0,0,0,13,11,10,4,7,
19、0,13,10,10,8,5,0,5,9,7,7,4,0,15,12,10,11,5,0,10,11,8,8,4;intmax1=0,g10,f10;boolp6=0;intgo(intstep,intt)/step是第几个人,是第几个人,t是之前已得的效益是之前已得的效益for(inti=1;i=5;i+)if(!pi)/判断判断(pndun)第第i项工作没人选择项工作没人选择fstep=i;/第第step个人,就选第个人,就选第i项工作项工作pi=1;/标记第标记第i项工作被人安排了项工作被人安排了t+=datastepi;/计算效益值计算效益值if(stepmax1)/保存最佳效益值保存
20、最佳效益值max1=t;for(intj=1;j=5;j+)gj=fj;/保存最优效益下的工作选择方案保存最优效益下的工作选择方案t-=datastepi;/回溯回溯pi=0;第17页/共45页第十七页,共45页。intmain()go(1,0);/从第从第1个人个人(grn),总效益为,总效益为0开始开始for(inti=1;i=5;i+)coutchar(64+i):Jgisetw(3);/输出各项工作安排情输出各项工作安排情况况coutendl;coutsupply:max1endl;/输出最佳效益值输出最佳效益值第18页/共45页第十八页,共45页。【例【例7】选书】选书学校放寒假时,
21、信息学竞赛辅导老师有学校放寒假时,信息学竞赛辅导老师有A,B,C,D,E五本书,要分给参加培五本书,要分给参加培训训(pixn)的张、王、刘、孙、李五位同学,每人只能选一本书。老师事先让每个人的张、王、刘、孙、李五位同学,每人只能选一本书。老师事先让每个人将自己喜欢的书填写在如下的表格中。然后根据他们填写的表来分配书本,希望设计将自己喜欢的书填写在如下的表格中。然后根据他们填写的表来分配书本,希望设计一个程序帮助老师求出所有可能的分配方案,使每个学生都满意。一个程序帮助老师求出所有可能的分配方案,使每个学生都满意。【算法分析】【算法分析】可用穷举法,先不考虑可用穷举法,先不考虑(kol)“每人
22、都满意每人都满意”这一条件,这样只剩这一条件,这样只剩“每人选一每人选一本且只能选一本本且只能选一本”这一条件。在这个条件下,可行解就是五本书的所有全排列,一这一条件。在这个条件下,可行解就是五本书的所有全排列,一共有共有5!=120种。然后在种。然后在120种可行解中一一删去不符合种可行解中一一删去不符合“每人都满意每人都满意”的解,留下的解,留下的就是本题的解答。的就是本题的解答。为了编程方便,设为了编程方便,设1,2,3,4,5分别表示这五本书。这五个数的一种全排列就分别表示这五本书。这五个数的一种全排列就是五本书的一种分发。例如是五本书的一种分发。例如54321就表示第就表示第5本书(
23、即本书(即E)分给张,第)分给张,第4本书(即本书(即D)分给王,分给王,第,第1本书(即本书(即A)分给李。)分给李。“喜爱书表喜爱书表”可以用二维数组来表示,可以用二维数组来表示,1表表示喜爱,示喜爱,0表示不喜爱。表示不喜爱。第19页/共45页第十九页,共45页。算法设计:S1:产生5个数字的一个全排列;S2:检查是否符合“喜爱(x i)书表”的条件,如果符合就打印出来;S3:检查是否所有的排列都产生了,如果没有产生完,则返回S1;S4:结束。int Search(i)for(j=1;j=5;j+)if(第i个同学分给第j本书符合条件)记录(jl)第i个数 if(i=5)打印一个解;el
24、se Search(i+1);删去第i 个数 上述算法有可以改进(gijn)的地方。比如产生了一个全排列 12345,从表中可以看出,选第一本书即给张同学的书,1是不可能的,因为张只喜欢第 3、4本书。这就是说,1一类的分法都不符合条件。由此想到,如果选定第一本书后,就立即检查一下是否符合条件,发现1是不符合的,后面的四个数字就不必选了,这样就减少了运算量。换句话说,第一个数字只在3、4中选择,这样就可以减少 3/5的运算量。同理,选定了第一个数字后,也不应该把其他 4个数字一次选定,而是选择了第二个数字后,就立即检查是否符合条件。例如,第一个数选3,第二个数选4后,立即检查,发现不符合条件,
25、就应另选第二个数。这样就把 34一类的分法在产生前就删去了。又减少了一部分运算量。综上所述,改进后的算法应该是:在产生排列时,每增加一个数,就检查该数是否符合条件,不符合,就立刻换一个,符合条件后,再产生下一个数。因为从第I本书到第I+1本书的寻找过程是相同的,所以可以用回溯算法。算法设计如下:第20页/共45页第二十页,共45页。【参考程序】【参考程序】#include#include#includeusingnamespacestd;intbook6,c;boolflag6,like66=0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,0,0,1,1,0,0,0,0
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 搜索 回溯 算法 学习 教案
限制150内