计算机算法与设计论文
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
中国传媒大学2011 学年第一学期计算机算法设计与分析课程
计算机算法设计与分析
题目回溯法解决n色方柱问题的算法设计与分析
学生姓名
学号
班级
学院
任课教师
回溯法解决n色方柱问题的算法设计与分析
摘要:
对于计算机科学来说,算法(Algorithm)的概念是至关重要的。算法是一系列解决问题的清晰指令,也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。为了充分理解算法分析的思想,利用算法思想解决实际问题,所以用回溯法解决书上P181习题5—7 n色方柱问题。
关键字:
计算机算法回溯法 n色方柱
回溯法背景:
回溯法也称为试探法,该方法首先暂时放弃关于问题规模大小的限制,并将问题的候选解按某种顺序逐一枚举和检验。当发现当前候选解不可能是解时,就选择下一个候选解;倘若当前候选解除了还不满足问题规模要求外,满足所有其他要求时,继续扩大当前候选解的规模,并继续试探。如果当前候选解满足包括问题规模在内的所有要求时,该候选解就是问题的一个解。在回溯法中,放弃当前候选解,寻找下一个候选解的过程称为回溯。扩大当前候选解的规模,以继续试探的过程称为向前试探。
回溯法的基本思想:确定了解空间的组织结构后,回溯法就从开始结点(根结点)出发,以深度优先的方式搜索整个解空间。这个开始结点就成为一个活结点,同时也成为当前的扩展结点。在当前的扩展结点处,搜索向纵深方向移至一个新结点。这个新结点就成为一个新的活结点,并成为当前扩展结点。如果在当前的扩展结点处不能再向纵深方向移动,则当前扩展结点就成为死结点。换句话说,这个结点不再是一个活结点。此时,应往回移动(回溯)至最近的一个活结点处,并使这个活结点成为当前的扩展结点。回溯法即以这种工作方式递归地在解空间中搜索,直至找到所要求的解或解空间中已没有活结点时为止。
1、问题描述:
设有n立方体,每个立方体的每个面用红、黄、蓝、绿等n种颜色之一染色。要把这n个立方体叠成一个方形柱体,使得柱体的4个侧面的每一侧均有n种不同的颜色。试设计一个回溯算法,计算出n个立方体的一种满足要求的叠置方案。
例如:第一行有1个正整数n,0 上图中F表示前面,B表示背面,L表示左面,R表示右面,T表示顶面,D表示底面。相应的2表示前面,3表示背面,0表示左面,1表示右面,5表示顶面,4表示底面。 2、算法分析: 此问题中,立方体的每对相对的面得颜色是要考察的关键因素。将每个立方体表示为有n个顶点的图。图中每个顶点表示一种颜色。在立方体每对向对面的顶点建连一条边。例如,图(b)是图(a)所示的4个立方体所相应的子图。 将上述子图合并,并标明每一条边来自哪一个立方体如图2所示。 下一步在构成的图中,找出2个特殊子图。一个子图表示叠置的n哥立方体的前侧面与背侧面,另一子图表示叠置的n个立方体的左侧面与右侧面。这两个子图应满足下述性质。 ①每个子图有n条边,且每个立方体恰好一条边。 ②2个子图没有公共边。 ③子图中每个顶点的度均为2。 对于图2中的图,找出满足要求的两个子图如图3所示。 给子图的每条边一个方向,使每个顶点有一条出边和一条入边。有向边得始点对应于 面和左面;有向边的终点对应于背面和右面。图3给出的满足要求的解如下。 0(L) 1(R)2(F) 3(B) Cube1 Y B G R Cube2 G Y R B Cube3 B R B Y Cube4 R G Y G 上述算法的关键是找满足性质(1)、(2)和(3)的子图。用回溯法。 3、实验数据与结果: 实验输入文件: input . txt 4 RGBBY 0 2 1 3 0 0 3 0 2 1 0 1 2 1 0 2 1 3 1 3 3 0 2 2 实验输出结果: output . txt RBGYRR YRBGRG BGRBGY GYYRBB 参考文献: 王晓东.计算机算法设计与分析(第3版)电子工业出版社 附录: 二维数组board[n][6]存储n个立方体各面的颜色,solu[n][6]存储解 ------------------------------------------------------------------------------------------------------- void search() { int i,t,cube,newg,over,ok; int *vert=new int[n]; int *edge=new int[n*2]; for(i=0;i t=-1;newg=1; while(t>-2){ t++; cube=t%n; //每个立方体找2次 if(newg)edge[t]=-1; over=0;ok=0; while(!ok && !over){ edge[t]++; if(edge[t]>2)over=1; //每个立方体只有3条边 else ok=(t if(!over){ if(++vert[board[cube][edge[t]*2]]>2+t/n*2)ok=0; if(++vert[board[cube][edge[t]*2+1]]>2+t/n*2)ok=0; if(t%n==n-1&&ok) //check that each vertex is order 2 for(i=0;i if(ok){if(t==n*2-1){ //找到解 ans++; out(edge); return; } else newg=1; } //ok else{ //取下一条边 --vert[board[cube][edge[t]*2]]; --vert[board[cube][edge[t]*2+1]]; t--;newg=0; } } //over else{ //回溯 t--; if(t>-1){ cube=t%n; --vert[board[cube][edge[t]*2]]; --vert[board[cube][edge[t]*2+1]]; } t--;newg=0; } } } --------------------------------------------