回溯法 马周.docVIP

  • 11
  • 0
  • 约4.74千字
  • 约 8页
  • 2017-02-01 发布于北京
  • 举报
实验课程:算法分析与设计 实验名称:回溯法的应用 第一部分 实验内容 1.实验目标 (1) 熟悉使用回溯法求解问题的基本思路。 (2)掌握回溯算法的程序实现方法。 (3)理解回溯算法的特点。 2. 实验任务 (1)从所给定的题目中选择一题,使用回溯法求解之。 (2)用文字来描述你的算法思路,包括解空间、限界函数、算法主要步骤等。 (3)在Windows环境下使用C/C++语言编程实现算法。 (4)记录运行结果,包括输入数据,问题解答及运行时间。 (5)分析算法最坏情况下时间复杂度和空间复杂度。 (6)谈谈实验后的感想,包括关于该问题或类似问题的求解算法的建议。 3. 实验设备及环境 PC;C/C++等编程语言。 4. 实验主要步骤 根据实验目标,明确实验的具体任务; 设计求解问题的回溯算法,并编写程序实现算法; 设计实验数据并运行程序、记录运行的结果; 分析算法时空性能; 实验后的心得体会。 第二部分 问题及算法 问题描述 问题1: 在一个8*8的棋盘上,一个放在棋盘上某个位置的马是否可以恰好访问每个方格一次,并且回到起始位置上? 2. 回溯法的一般思路 深度优先搜索,若寻找到满足要求的解,则输出;否则推回上一层往下一个方向搜索。 3. 求解问题的回溯算法描述 对于当前所在位置(x,y),依次枚举8个方向搜索,直到找到一组可行解为止。使用剪枝有3处:第一、使用Warnsdorffs rule,枚举当前解得时候优先选择下一步可行步数最少的方向;第二、若第一点中的方向存在不止一个,则优先选择离中心位置较远的方向;每次都从中心点开始出发,求出一条合法路径后再平移映射回待求路径。 4. 算法实现的关键技巧 在棋盘较大的时候,使用递归会使得函数暴栈,故应当使用非递归方法实现。程序实现时应细心记录清楚当前状态在栈顶。 第三部分 实验结果与分析 #include cstdio #include cstring #include algorithm #include ctime using namespace std; const int ix[8] = {1, 2, 2, 1, -1, -2, -2, -1}; const int iy[8] = {2, 1, -1, -2, 2, 1, -1, -2}; int midx, midy; struct Point { int x, y, c; Point(int xx = 0, int yy = 0, int cc = 0):x(xx), y(yy), c(cc) {} bool operator (const Point b) const { if (c != b.c) return c b.c; return abs(x - midx) + abs(y - midy) abs(b.x - midx) + abs(b.y - midy); } }; struct Node { int x, y; Node(int xx = 0, int yy = 0):x(xx), y(yy) {} }; template class T inline void swap(T a, T b) { T t = a; a = b; b = t; } int m, n; bool vis[10][10]; int a[10][10]; inline bool check(int x, int y) { if (x 1 || x n || y 1 || y n) return 0; if (vis[x][y]) return 0; return 1; } bool find(int x, int y) { for (int i = 0; i 8; ++i) if (x + ix[i] == midx y + iy[i] == midy) return 1; return 0; } Node ss[10 * 10]; Point b[10 * 10][8], *tb; int dir[10 * 10], bn[10 * 10], top; bool dfs(int x, int y) { int i, j, tbn, nx, ny, mx, my, cnt; top = 1; vis[x][y] = 1; a[x][y] = 0; ss[top] = Node(x, y); dir[top] =

文档评论(0)

1亿VIP精品文档

相关文档