回溯法

阅读: 评论:0

回溯法

回溯法

在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在n×n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。

                                  

利用回溯法:

回溯法的基本做法是搜索,或是一种组织得井井有条的,能避免不必要搜索的穷举式搜索法。这种方法适用于解一些组合数相当大的问题。 回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树。算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解。如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯;否则,进入该子树,继续按深度优先策略搜索。

解法

(1)针对所给问题,定义问题的解空间;

(2)确定易于搜索的解空间结构(递归树);

(3)以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。

一般递归代码如下:

void backtrack(int t)//传递值通过参数
{if (t>n) output(x);elsefor (int i=f(n,t);i<=g(n,t);i++) {x[t]=h(i);//记录中间结果!if (constraint(t)&&bound(t)) backtrack(t+1);//限制条件加边界}
}
迭代代码

void iterativeBacktrack ()
{int t=1;while (t>0) {if (f(n,t)<=g(n,t)) for (int i=f(n,t);i<=g(n,t);i++) {x[t]=h(i);if (constraint(t)&&bound(t)) {if (solution(t)) output(x);else t++;}}else t--;}


此n皇后问题分析

1、解空间(0,n-1)

2、结构为一递归树,基本上每个有n个子节点

3、减枝函数为:不能同行,同列,对角线上


如何规划n*n的空间呢?

----令解空间为A[i] ----值范围为:0-n-1。列为i,用level表示当前层次

(S[i] == val || abs(S[i]-val) == abs(i-level)) //同列,对角线上,此种方法不会出现同行故未考虑

以下为实现代码:

#include <iostream>
#include <cmath>
using namespace std;int count_path();
void print_path(int S[],int n);
bool check(int level,int val,int S[]);
void trace_path(int n,int level,int S[]);
void nqueen(int n);int main()
{int n(0);cout<<"please input n";cout<<endl;cin>>n;nqueen(n);cout<<count_path()-1;return 0;
}bool check(int level,int val,int S[])
{for (int i = 0;i < level ;i++){if (S[i] == val || abs(S[i]-val) == abs(i-level)){return false;}}return true;
}void trace_path(int n,int level,int S[])
{if(level >= n){cout<<"find path:";print_path(S,n);count_path();cout<<endl;return ;}else{for(int i = 0 ;i < n;i++){if(check(level,i,S)){S[level] = i;trace_path(n,level+1,S);}}}}void nqueen(int n)
{if (n > 20){cout<< "值太大!小于20."<<endl;return ;}int *S = new int [n];trace_path(n,0,S);
}void print_path(int S[],int n)
{for (int i = 0;i < n;i++){cout<<S[i]<<"t";}
}
int count_path()
{static int count = 0;count++;return count;
}

测试:

please input n = 4
2
find path:1     3       0       2
find path:2     0       3       1

please input n = 6
4
find path:1     3       5       0       2       4
find path:2     5       1       4       0       3
find path:3     0       4       1       5       2
find path:4     2       0       5       3       1


please input n = 3
0


结果太多略:
please input n = 8
92
please input n = 7
40






本文发布于:2024-01-30 22:07:49,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170662367123165.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23