- 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)