【跳马问题】“回溯法”——《算法设计与分析(第五版)》
2022/1/15 20:05:16
本文主要是介绍【跳马问题】“回溯法”——《算法设计与分析(第五版)》,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- 一、算法要求
- 1. 思路
- 二、完整代码
- 1. 主文件
- 2. 头文件
- 3. 效果展示
- 三、补充
一、算法要求
问题描述:在 N*N 棋盘上有 N^2个格子,马在初始位置(X0,Y0),按照象棋中马走“日” 的规则,
使马走遍全部格子且每个格子仅经过一次。编程输出马的走法。
编程实现,给出 N=5,(X0,Y0)=(1,1)时的运行结果。
1. 思路
有许多问题,当需要找出它的解集或者要求回答什么解是满足某些约束条件的最佳解时,往往要使用回溯法。
回溯法的基本做法是搜索,或是一种组织得井井有条的,能避免不必要搜索的穷举式搜索法。这种方法适用于解一些组合数相当大的问题。
回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树。
算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解。如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯;否则,进入该子树,继续按深度优先策略搜索。
二、完整代码
1. 主文件
main.cpp:
// Project4_2: 用回溯法求解跳马问题 #include"Improve2.h" int main() { //初始数据 const int lengthBoard = 5, begingX = 1, begingY = 1; //打印初始数据 cout << "#The initial data are as follows: \n" << "\tLength of the chessboard: " << lengthBoard << endl << "\tInitial coordinates: ( " << begingX << " , " << begingY << " )" << endl; Console(); // 调用回溯函数 Backtracking(auxiliaryX, auxiliaryY); // 打印方法数量 cout << "#The number of possible methods in total is: " << countMethod << endl; return 0; }
2. 头文件
Improve2.h:
#pragma once #ifndef __IMPROVE2__ #define __IMPROVE2__ #include <iostream> #include <iomanip> #include <cmath> using namespace std; //初始数据 const int lengthBoard = 5, begingX = 1, begingY = 1; int countStep = 0, // 标记第几步 countMethod = 1; // 标记这是第几种可能的输出 const int auxiliaryBoard = lengthBoard + 4, auxiliaryX = begingX + 1, auxiliaryY = begingY + 1; int meansMove[8][2], // 保存八种走法 chessBoard[auxiliaryBoard][auxiliaryBoard]; // 棋盘 void Console() { //初始化棋盘 int i, j; for (i = 0; i < 2; i++) {//up for (j = 0; j < auxiliaryBoard; j++) { chessBoard[i][j] = -1; } } for (i = auxiliaryBoard - 2; i < auxiliaryBoard; i++) {//down for (j = 0; j < auxiliaryBoard; j++) { chessBoard[i][j] = -1; } } for (i = 0; i < auxiliaryBoard; i++) {//left for (j = 0; j < 2; j++) { chessBoard[i][j] = -1; } } for (i = 0; i < auxiliaryBoard; i++) {//right for (j = auxiliaryBoard - 2; j < auxiliaryBoard; j++) { chessBoard[i][j] = -1; } } for (i = 2; i < auxiliaryBoard - 2; i++) {//inside for (j = 2; j < auxiliaryBoard - 2; j++) { chessBoard[i][j] = 0; } } //初始化八种走法meansMove[x][y] meansMove[0][0] = 2; meansMove[0][1] = 1; // {x+2,y+1} meansMove[1][0] = 1; meansMove[1][1] = 2; // {x+1,y+2} meansMove[2][0] = -1; meansMove[2][1] = 2; // {x-1,y+2} meansMove[3][0] = -2; meansMove[3][1] = 1; // {x-2,y+1} meansMove[4][0] = -2; meansMove[4][1] = -1; // {x-2,y-1} meansMove[5][0] = -1; meansMove[5][1] = -2; // {x-1,y-2} meansMove[6][0] = 1; meansMove[6][1] = -2; // {x+1,y-2} meansMove[7][0] = 2; meansMove[7][1] = -1; // {x+2,y-1} chessBoard[auxiliaryX][auxiliaryY] = ++countStep; // 初始步数 } // 打印棋盘 void Display() { cout << "\n#The following is a simple situation: " << endl; for (int i = 2; i < auxiliaryBoard - 2; i++) { for (int n = 0; n < lengthBoard; n++) cout << "+--"; cout << "+" << endl; for (int j = 2; j < auxiliaryBoard - 2; j++) { if (chessBoard[i][j] < auxiliaryBoard - 2) cout << "|" << setw(2) << chessBoard[i][j] ; else cout << "|" << setw(2) << chessBoard[i][j] ; } cout << "|" << endl; } for (int m = 0; m < lengthBoard; m++) cout << "+--"; cout << "+\n" << endl; } // 跳马回溯函数 void Backtracking(int x, int y) { if (countStep == (lengthBoard*lengthBoard)) {//终止条件 countMethod++; if (countMethod == 2) { Display(); } } int i; for (i = 0; i < 8; i++) { // 8种可能跑法 // 计算准备要走的这一步的位置 int a = x + meansMove[i][0]; int b = y + meansMove[i][1]; if (chessBoard[a][b] == 0) { // 能走 chessBoard[a][b] = ++countStep; // 标记 Backtracking(a, b); // 向下走 chessBoard[a][b] = 0; // 退回来,还原状态 countStep--; // 对称处理 } } } #endif
3. 效果展示
三、补充
回溯算法效率
问题的解向量:回溯法希望一个问题的解能够表示成一个n元式(x1,x2,…,xn)的形式。
显约束:对分量xi的取值限定。
隐约束:为满足问题的解而对不同分量之间施加的约束。
解空间:对于问题的一个实例,解向量满足显式约束条件的所有多元组,构成了该实例的一个解空间。
注意:同一个问题可以有多种表示,有些表示方法更简单,所需表示的状态空间更小(存储量少,搜索方法简单)。
文档供本人学习笔记使用,仅供参考。
这篇关于【跳马问题】“回溯法”——《算法设计与分析(第五版)》的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-12百万架构师第十五课:源码分析:Spring 源码分析:SpringMVC核心原理及源码分析|JavaGuide
- 2025-01-11有哪些好用的家政团队管理工具?
- 2025-01-11营销人必看的GTM五个指标
- 2025-01-11办公软件在直播电商前期筹划中的应用与推荐
- 2025-01-11提升组织效率:上级管理者如何优化跨部门任务分配
- 2025-01-11酒店精细化运营背后的协同工具支持
- 2025-01-11跨境电商选品全攻略:工具使用、市场数据与选品策略
- 2025-01-11数据驱动酒店管理:在线工具的核心价值解析
- 2025-01-11cursor试用出现:Too many free trial accounts used on this machine 的解决方法
- 2025-01-11百万架构师第十四课:源码分析:Spring 源码分析:深入分析IOC那些鲜为人知的细节|JavaGuide