数据结构第六章第五节.ppt
《数据结构第六章第五节.ppt》由会员分享,可在线阅读,更多相关《数据结构第六章第五节.ppt(89页珍藏版)》请在三一办公上搜索。
1、6.7 回溯法和树的遍历,回溯的一般描述 回溯法的基本框架 应用举例,6.7.1 回溯的一般描述,回溯法(Backtracking),“通用的解题法”,基本原理:以“深度优先”的方式系统地“搜索”一个问题的一组解或所有解,适用场合适合于求解组合数较大的问题,问题的解必须能用一个n元组表示 X=(x1,x2,xn),xi Si,(i=1,2,n)mi=|Si|,(i=1,2,n),求出使得规范函数 P(x1,x2,xn)取极大值(或极小值或满足规范函数的约束条件)的所有向量,应用条件,(1)xi 0 即 Si=所有非负实数(2)xi=0 或 xi=1 即 Si=0,1(3)li xi ui 即
2、Si=a,li a ui,显式约束可以与所求解的问题的实例I有关,也可以无关。满足显示约束的所有元组确定问题的一个“可能的”解空间,显式约束:限定每个x只能从一个给定的集合上取值,隐式约束:规定I的解空间中那些实际上满足规范函数的元组。隐式约束描述了xi必须“彼此相关”的情况,约束条件,例 八皇后问题,(i+1,j+1),(i+1,j),(i+1,j-1),(i,j+1),(i,j),(i,j-1),(i-1,j+1),(i-1,j),(i-1,j-1),N皇后问题,八皇后问题,X=(x1,x2,x8),(2)显式约束条件:,(1)问题解表达式:,Si=1,2,3,4,5,6,7,8,1 i
3、8,(3)隐式约束条件:,(xixj)&(abs(xi-xj)abs(i-j)1 i,j 8,(4)解空间:,88,8!,X=(4,6,8,2,7,6,3,5),?,x1=1,x2=2,x2=4,x2=3,3,4,4,3,x2=1,x2=4,x2=3,3,4,x1=2,2,4,4,2,2,3,3,2,4,3,4,1,3,1,1,4,1,3,x2=1,x2=4,x2=2,2,4,x1=3,1,4,1,3,4,2,4,1,3,1,x2=1,x2=3,x2=2,2,3,x1=4,1,3,1,2,3,2,3,1,2,1,4皇后问题的状态空间树,1,并查集的树表示,int BACKTRACK(n)/这是
4、对回溯法控制流程的抽象描述。每个解都在x1.n中生成,一个解一/经确定就立即印出。在x1,xk已选定的情况下,T(x1,xk-1)给出/xk所有可能的取值。限界函数B(x1,xk)判断哪些元素xk满足隐式约/束条件 k=1;while(k0)if 还剩有未检验过的xk,使得 xkT(x1,xk)and B(x1,xk)=TRUE if(x1,xk)是一条已抵达答案结点的路径 print(x1,xk);else k=k+1;/考虑下一个集合/if else k=k-1;/回溯到先前的集合/while/BACKTRACK,并查集的树表示,void RBACKTRACK(k)/这是对回溯法控制流程的
5、抽象地递归描述。进入算法时,解/向量X1.n的前k-1个分量x1,xk-1已赋值 for 满足下式的每个xk xkT(x1,xk)and B(x1,xk)=TRUE if(x1,xk)是一条已抵达答案结点的路径 print(x1,xk);else RBACKTRACK(k+1);/for/BACKTRACK,置行计数i=1;放置第一个棋子,将棋子位置压入堆栈;while(i=4)i+;在i行的适当位置放置一个棋子,检查位置的合法性;if 位置合法,then 将棋子位置压入堆栈;else while(栈不空)删除栈顶元素;i-;在第i行重试下一个合法位置;if 找到一个合法位置,then 将新位
6、置压入堆栈;break;/while(栈不空)/else/while(i=4),四皇后,四皇后,void place(int i,int n)/进入本函数时,在nxn棋盘前i-1行已放置了互不攻击的i-1个棋子/现从第i行起继续为后续棋子选择合适位置/当(in)时,求得一个合法布局,输出之 if(in)输出棋盘的当前布局;/n为4时,即为4皇后问题 else for(j=1;j=n;+j)在第i行第j列放置一个棋子;if(当前布局合法)place(i+1,n);移走第i行第j列的棋子;/place,四皇后,void place(int i,int n)/进入本函数时,在nxn棋盘前i-1行已放
7、置了互不攻击的i-1个棋子/现从第i行起继续为后续棋子选择合适位置/当(in)时,求得一个合法布局,输出之 if(in)输出棋盘的当前布局;/n为4时,即为4皇后问题 else for(j=1;j=n;+j)在第i行第j列放置一个棋子;if(当前布局合法)place(i+1,n);移走第i行第j列的棋子;/place,应用举例,1.求出n位二进制数的所有编码,2.求含n个元素的幂集,A=1,2,3,(A)=1,2,3,1,2,1,3,1,2,3,2,3,3.假设有n个不同的正数,请找出这些数中所有使得某和数为M的所有组合,n=4,(w1,w2,w3,w4)=(11,13,24,7),M=31,
8、X=(1,2,4)和(3,4),1.求出n位二进制数的所有编码,void BinCoding(int b,int k)/n位二进数的编码放在数组b0.n-1中/假设前面k位的编码已完成,/现在对k+1位进行编码 if(k=n)printf(“%d”,b);/编码结束,输出 else bk=1;BinCoding(b,k+1);bk=0;BinCoding(b,k+1);/BinCoding,主调用 BinCoding(a,0),x1=1,x1=0,1,0,1,0,1,0,x2=1,0,x3=1,0,1,0,2.求含n个元素的幂集,1,2,3,1,2,1,3,1,2,3,2,3,1,2,1,1,
9、2,取1,舍1,A=1,2,3,取2,舍2,取2,舍2,取3,舍3,取3,舍3,取3,舍3,取3,舍3,void Powerset(int i,int n)/求含n个元素的集合A的幂集p(A)./进入函数时已对A中前 i-1 个元素作了取舍处理/现从第i个元素起进行取舍处理。若in,则求得幂集的一个元素,/并输出之,初始调用:PowerSet(1,n)if(in)输出幂集的一个元素else 取第i个元素;PowerSet(i+1,n);舍第i个元素;PowerSet(i+1,n);/PowerSet,void GetPowerset(int i,List A,List/GetPowerSet,
10、取11,n=4,(w1,w2,w3,w4)=(11,13,24,7),M=31,舍11,取13,舍13,取13,舍13,取24,舍24,取24,舍24,取24,舍24,取24,舍24,取7,舍7,取7,舍7,取7,取7,取7,舍7,舍7,舍7,3.和数问题(背包问题),void Knapsack(int weight,int num,int k)/对前面k-1个数字进行取舍的结果放在num0.k-1中/假设前面k个数字的取舍已完成,/现在对k+1个数字进行取舍 if(weight=M)output(num,k);/输出结果 else if(weightM)|(k=n)return;else n
11、umk=1;Knapsack(weight+wk,num,k+1);numk=0;Knapsack(weight,num,k+1);/Knapsack,int w=11,13,24,7;int M=31;int num4;,void output(int num,int count)int i;for(i=0;icount;i+)if(numi)printf(%d,wi);printf(n);,void main()Knapsack(num,0,0);printf(wait to exit);,11,13,7,24,11,7,24,13,11,7,13,24,11,24,13,7,24,7,2
12、4,7,13,24,11,24,13,24,11,24,和数问题的状态空间树,n=4,(w1,w2,w3,w4)=(11,13,24,7),M=31,int w=11,13,24,7;int M=31;int num4;int visit4=0,0,0,0;void Knapsack1(int num,int weight,int k)if(weight=M)output1(num,k);else if(weightM)|(k=4)return;elsefor(i=0;i4;i+)if(!visiti)visiti=TRUE;numk=wi;Knapsack1(num,weight+wi,k+
13、1);visiti=FALSE;/for/else,6.5 树与等价问题,等价关系与等价类 并查集 路径压缩 应用举例,6.5.1 等价关系与等价类,一般地,一个集合S中的所有对象可以通过等价关系划分为m个互不相交的子集S1,S2,Sm,即对于S中的任何两个元素x和y(x,yS),如果x和y是等价的(xy),则x和y被划分在同一个子集Si中(i=1,2,m).这些子集被成为等价类,利用等价关系把集合S划分为若干等价类的算法分为两步:,(1)首先把S中的每一个对象看成是一个等价类;(2)依次处理各个等价对(xy);若xSi,ySj,且SiSj,则把集合Si,Sj合并成一个集合,6.5.1 等价关
14、系与等价类,例:给定集合S=a,b,c,d,e,f,g,h,i,j,以及如下等价对 ab,gd,ij,cb,ac,hi,fe,fd,试划分等价类。,初始,a,b,c,d,e,f,g,h,i,j,ab,a,b,c,d,e,f,g,h,i,j,gd,a,b,c,d,g,e,f,h,i,j,ij,a,b,c,d,g,e,f,h,i,j,cb,a,b,c,d,g,e,f,h,i,j,S=a,b,c,d,e,f,g,h,i,j,ab,gd,ij,cb,ac,hi,fe,fd,ac,a,b,c,d,g,e,f,h,i,j,hi,a,b,c,d,g,e,f,h,i,j,fe,a,b,c,d,g,e,f,h,
15、i,j,fd,a,b,c,d,g,e,f,h,i,j,S1,S2,S3,划分等价类的过程,并查集的ADT定义,数据对象:,数据关系:,ADT MFSet,若设S是MFSet型的集合,则它由n(n0)个子集Si(i=1,2,n)构成,每个子集的成员都属于同一数据对象,栈的抽象数据类型,基本操作:(1)InitMFSet(/归并操作。将Si和Sj中的一个并入另一个中 ADT MFSet,并查集的树表示,S1=a,b,c,S2=d,g,e,f,S3=h,i,j,a,b,c,d,e,f,g,h,i,j,S1,S2,S3,并查集的树表示,S1=a,b,c,S2=d,g,e,f,S3=h,i,j,a,b,
16、c,d,e,f,g,h,i,j,S1,S2,S3,a,b,c,d,e,f,g,h,i,j,S1S2,S3,合并操作,d,e,f,a,b,c,h,i,j,S1S2,S3,g,合并操作,typedef PTree MFSet,#define MAX_TREE_SIZE 100typedef struct PTNode TElemType data;int parent;/双亲位置域PTNode;typedef struct PTNode nodesMAX_TREE_SIZE;int n;/结点数PTree;,int find_mfset(MFSet S,TElemType x)/找集合S中元素x所
17、在子集的根的位置 i=Locate(S,x);/确定x所在的位置,如果不存在,返回-1;if(i=-1)return 1;/元素x不属于任一子集 for(j=i;S.nodesj.parent 0;j=S.nodesj.parent;return j;/find_mfset,d,e,f,a,b,c,S,g,int find_mfset(MFSet S,TElemType x)/找集合S中元素x所在子集的根的位置 i=Locate(S,x);/确定x所在的位置,如果不存在,返回-1;if(i=-1)return 1;/元素x不属于任一子集 for(j=i;S.nodesj.parent 0;j=
18、S.nodesj.parent;return j;/find_mfset,d,e,f,a,b,c,S,g,int find_mfset(MFSet S,TElemType x)/找集合S中元素x所在子集的根的位置 i=Locate(S,x);/确定x所在的位置,如果不存在,返回-1;if(i=-1)return 1;/元素x不属于任一子集 for(j=i;S.nodesj.parent 0;j=S.nodesj.parent;return j;/find_mfset,d,e,f,a,b,c,S,g,j=1,int find_mfset(MFSet S,TElemType x)/找集合S中元素x
19、所在子集的根的位置 i=Locate(S,x);/确定x所在的位置,如果不存在,返回-1;if(i=-1)return 1;/元素x不属于任一子集 for(j=i;S.nodesj.parent 0;j=S.nodesj.parent;return j;/find_mfset,d,e,f,a,b,c,S,g,j=0,int find_mfset(MFSet S,TElemType x)/找集合S中元素x所在子集的根的位置 i=Locate(S,x);/确定x所在的位置,如果不存在,返回-1;if(i=-1)return 1;/元素x不属于任一子集 for(j=i;S.nodesj.parent
20、 0;j=S.nodesj.parent;return j;/find_mfset,d,e,f,a,b,c,S,g,j=3,int find_mfset(MFSet S,TElemType x)/找集合S中元素x所在子集的根的位置 i=Index(S,x);/确定x所在的位置,如果不存在,返回-1;if(i=-1)return 1;/元素x不属于任一子集 for(j=i;S.nodesj.parent 0;j=S.nodesj.parent;return j;/find_mfset,d,e,f,a,b,c,S,g,j=3,int find_mfset(MFSet S,TElemType x)/
21、找集合S中元素x所在子集的根的位置 i=Index(S,x);/确定x所在的位置,如果不存在,返回-1;if(i=-1)return 1;/元素x不属于任一子集 for(j=i;S.nodesj.parent 0;j=S.nodesj.parent;return j;/find_mfset,d,e,f,a,b,c,S,g,并查集的树表示,d,e,f,g,S2,a,b,c,S1,i=0,j=3,int union_mfset(MFSet S,int i,int j)/S.nodesi和S.nodesj分别为S的互不相交的两个/子集Si和Sj的根结点,求并集SiSj if(iS.n|jS.n)re
22、turn ERROR;S.nodesj.parent=S.nodesi.parent+S.nodesj.parent S.nodesi.parent=j;return OK;/merge_mfset,并查集的树表示,d,e,f,g,S2,a,b,c,S1,i=0,j=3,int union_mfset(MFSet S,int i,int j)/S.nodesi和S.nodesj分别为S的互不相交的两个/子集Si和Sj的根结点,求并集SiSj if(iS.n|jS.n)return ERROR;S.nodesj.parent=S.nodesi.parent+S.nodesj.parent S.n
23、odesi.parent=j;return OK;/merge_mfset,并查集的树表示,d,e,f,g,S2,a,b,c,S1,i=0,j=3,-7,int union_mfset(MFSet S,int i,int j)/S.nodesi和S.nodesj分别为S的互不相交的两个/子集Si和Sj的根结点,求并集SiSj if(iS.n|jS.n)return ERROR;S.nodesj.parent=S.nodesi.parent+S.nodesj.parent S.nodesi.parent=j;return OK;/merge_mfset,并查集的树表示,d,e,f,g,S2,a,
24、b,c,S1,i=0,j=3,3,-7,int union_mfset(MFSet S,int i,int j)/S.nodesi和S.nodesj分别为S的互不相交的两个/子集Si和Sj的根结点,求并集SiSj if(iS.n|jS.n)return ERROR;S.nodesj.parent=S.nodesi.parent+S.nodesj.parent S.nodesi.parent=j;return OK;/merge_mfset,并查集的树表示,i=0,j=3,3,-7,3,int union_mfset(MFSet S,int i,int j)/S.nodesi和S.nodesj分
25、别为S的互不相交的两个/子集Si和Sj的根结点,求并集SiSj if(iS.n|jS.n)return ERROR;S.nodesj.parent=S.nodesi.parent+S.nodesj.parent S.nodesi.parent=j;return OK;/merge_mfset,d,e,f,a,b,c,S1S2,g,并查集的树表示,i=0,j=3,3,-7,3,int union_mfset(MFSet S,int i,int j)/S.nodesi和S.nodesj分别为S的互不相交的两个/子集Si和Sj的根结点,求并集SiSj if(iS.n|jS.n)return ERRO
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 第六 五节
链接地址:https://www.31ppt.com/p-6578936.html