JAVA求解N皇后问题代码及答案
N皇后问题java实现

N皇后问题java实现N皇后问题是⼀个典型的约束求解问题,利⽤递归机制,可以很快的得到结果。
N皇后问题的描述:在⼀个n*n的棋盘上,摆放n个皇后,要求每个皇后所在⾏、列、以及两个对⾓线上不能出现其他的皇后,否则这些皇后之间将会相互攻击。
如下图所⽰。
利⽤递归机制,可以很容易的求解n皇后问题。
针对⼋皇后,总共有92种解。
下⾯将给出N-皇后问题的⼀般求解代码,在这⾥代码是使⽤java编码的。
总共设计了三个类,⼀个是皇后类(Queen),⼀个棋盘类(Board),⼀个是求解主程序类(NQueens)。
具体代码如下:1: import java.util.ArrayList;2: import java.util.List;3:4: public class NQueens {5:6: private int numSolutions;//求解结果数量7: private int queenSize;//皇后的多少8: private Board board;//棋盘9: private List<Queen> queens = new ArrayList<Queen>();//皇后10: //private List<Queen> nQueens = new ArrayList<Queen>();11:12: public NQueens(){13:14: }15:16: public NQueens(int size){17: numSolutions = 0;18: queenSize = size;19: board = new Board(queenSize);20: for (int i = 0; i < queenSize; i++) {21: Queen queen = new Queen();22: queens.add(queen);23: }24:25: }26:27: public void solve(){28: System.out.println("Start solve....");29: putQueen(0);30: }31:32: private void putQueen(int index){33:34: int row = index;35: //如果此列可⽤36: for (int col = 0; col < board.getQueenSize(); col++) {37: if (board.getLayout()[row][col] == 0) {38: //将皇后的位置置为此列位置39: queens.get(row).setPosition(col);40: //然后将相应的位置(此列的正下⽅以及两个对⾓线)加1(即使其不可⽤) 41: for (int i = row + 1; i < board.getQueenSize(); i++) {42: board.getLayout()[i][col] ++;43: if (row + col - i >= 0) {44: board.getLayout()[i][row + col - i] ++;45: }46: if (i + col - row < board.getQueenSize()) {47: board.getLayout()[i][i + col - row] ++;48: }49: }50:51: if (row == board.getQueenSize()-1) {52: numSolutions++;53: printSolution(numSolutions);54: }else {55: putQueen(row + 1);56: }57: //回溯,将相应的位置(此列的正下⽅以及两个对⾓线)减158: for (int i = row + 1; i < board.getQueenSize(); i++) {59: board.getLayout()[i][col] --;60: if (row + col - i >= 0) {61: board.getLayout()[i][row + col - i] --;62: }63: if (i + col - row < board.getQueenSize()) {64: board.getLayout()[i][i + col - row] --;65: }66: }67:68: }69: }70: }71: //打印求解结果72: private void printSolution(int i){73: System.out.println("The "+i+ " solution is:");74: for (int j = 0; j < board.getQueenSize(); j++) {75: for (int k = 0; k < board.getQueenSize(); k++) {76: System.out.print(queens.get(j).getPosition() == k ? " * ":" - ");77: }78: System.out.println();79: }80: System.out.println();81: }82: /**83: * @param args84: */85: public static void main(String[] args) {86: //可以改变参数87: NQueens nQueens = new NQueens(8);88: nQueens.solve();89:90: }91:92:93:94: }95: import java.io.Serializable;96:97: //皇后类98: public class Queen implements Serializable, Cloneable {99:100: /**101: *102: */103: private static final long serialVersionUID = 7354459222300557644L; 104: //皇后的位置105: private int position;106:107: public Queen(){108:109: }110:111: public int getPosition() {112: return position;113: }114:115: public void setPosition(int position) {116: this.position = position;117: }118:119: public Object clone() throws CloneNotSupportedException {120:121: return super.clone();122: }123: }124:125: import java.io.Serializable;126:127: //棋盘类128: public class Board implements Serializable,Cloneable {129:130: /**131: *132: */133: private static final long serialVersionUID = -2530321259544461828L; 134:135: //棋盘的⼤⼩136: private int queenSize;137:138: //棋盘的布局139: private int[][] layout;140:141: public Board(int size){142: this.queenSize = size;143: yout = new int[queenSize][queenSize];144: //初始化,使棋盘所有位置都可⽤,即全部置为0145: for (int i = 0; i < queenSize; i++) {146: for (int j = 0; j < queenSize; j++) {147: layout[i][j] = 0;148:149: }150: }151: }152:153: public int getQueenSize() {154: return queenSize;155: }156:157: public void setQueenSize(int queenSize) {158: this.queenSize = queenSize;159: }160:161: public int[][] getLayout() {162: return layout;163: }164:165: public void setLayout(int[][] layout) {166: yout = layout;167: }168:169: public Object clone() throws CloneNotSupportedException { 170:171: return super.clone();172: }173:174: }175:。
回溯法实验(n皇后问题)(迭代法)

算法分析与设计实验报告第三次附加实验附录:完整代码(回溯法)//回溯算法递归回溯n皇后问题#include<iostream>#include<time.h>#include<iomanip>#include"math.h"using namespace std;class Queen{friend int nQueen(int); //定义友元函数,可以访问私有数据private:bool Place(int k); //判断该位置是否可用的函数void Backtrack(int t); //定义回溯函数int n; //皇后个数int *x; //当前解long sum; //当前已找到的可行方案数};int main(){int m,n;for(int i=1;i<=1;i++){cout<<"请输入皇后的个数:"; //输入皇后个数cin>>n;cout<<"皇后问题的解为:"<<endl;clock_t start,end,over; //计算程序运行时间的算法start=clock();end=clock();over=end-start;start=clock();m=nQueen(n); //调用求解的函数cout<<n<<"皇后问题共有";cout<<m<<"个不同的解!"<<endl; //输出结果end=clock();printf("The time is %6.3f",(double)(end-start-over)/CLK_TCK); //显示运行时间cout<<endl;}system("pause");return 0;}bool Queen::Place(int k)//传入行号{for(int j=1;j<k;j++){if((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k]))//如果两个在同一斜线或者在同一列上,说明冲突,该位置不可用{return false;}}return true;}void Queen::Backtrack(int t){if(t>n){sum++;/*for(int i=1;i<=n;i++) //输出皇后排列的解{cout<<x[i]<<" ";}cout<<endl;*/}else{//回溯探索第i行的每一列是否有元素满足要求for(int i=1;i<=n;i++){x[t]=i;if(Place(t)){Backtrack(t+1);}}}}int nQueen(int n){Queen X; //定义Queen类的对象X//初始化XX.n=n;X.sum=0;int *p=new int[n+1]; //动态分配for(int i=0;i<=n;i++) //初始化数组{p[i]=0;}X.x=p;X.Backtrack(1);delete[] p;return X.sum;//输出解的个数}完整代码(回溯法)//回溯算法迭代回溯n皇后问题#include<iostream>#include<time.h>#include<iomanip>#include"math.h"using namespace std;class Queen{friend int nQueen(int); //定义友元函数private:bool Place(int k); //定义位置是否可用的判断函数void Backtrack(void); //定义回溯函数int n; // 皇后个数int *x; // 当前解long sum; // 当前已找到的可行方案数};int main(){int n,m;for(int i=1;i<=1;i++){cout<<"请输入皇后的个数:";cin>>n;cout<<n<<"皇后问题的解为:"<<endl;clock_t start,end,over; //计算程序运行时间的算法start=clock();end=clock();over=end-start;start=clock();m=nQueen(n); //调用求解皇后问题的函数cout<<n<<"皇后问题共有";cout<<m<<"个不同的解!"<<endl;end=clock();printf("The time is %6.3f",(double)(end-start-over)/CLK_TCK); //显示运行时间cout<<endl;}system("pause");return 0;}bool Queen::Place(int k){for (int j=1;j<k;j++){if ((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k])) //如果两个皇后在同一斜线或者在同一列上,说明冲突,该位置不可用{return false;}}return true;}void Queen::Backtrack() //迭代法实现回溯函数{x[1] = 0;int k = 1;while(k>0){x[k] += 1; //先将皇后放在第一列的位置上while((x[k]<=n)&&!(Place(k))) //寻找能够放置皇后的位置{x[k] += 1;}if(x[k]<=n) //找到位置{if(k == n) //如果寻找结束输出结果{/*for (int i=1;i<=n;i++){cout<<x[i]<<" ";}cout<<endl; */sum++;}else//没有结束则找下一行{k++;x[k]=0;}}else//没有找到合适的位置则回溯{ k--; }}}int nQueen(int n){Queen X; //定义Queen类的对象X//初始化XX.n=n;X.sum=0;int *p=new int[n+1];for(int i=0;i<=n;i++){p[i]=0;}X.x=p;X.Backtrack();delete []p;return X.sum; //返回不同解的个数}。
N后问题

有题目我们可以直到n后问题的具体所指,针对这个问题暂时还 没有令人信服的数学结论,所以用回朔方法举出所有的情况是 一种方法。但是若是对每一个格子进行回朔其时间复杂度是2的 n*n次方。运算量及其庞大,针对这种情况我们选择一种改良算 法。即把每一行看成一个变量进行n次穷举,则时间复杂度下降 到n的n次方。在一定的数据范围内是可以接受的。
N后问题 回朔算法的巧妙使用
问题描述 将n个皇后放在n x n的棋盘上,使得任何2 个皇后不能被放在同一行或同一列或同一 斜线上。 输入 输入包括干个测试用例,第一行为一个正 整数K(1<=k<=10)表示用例个数,每个 用例占一行N(1<=N<=10),表示皇后数。 输出 每个用例,用一行输出符合条件的放置种 数。
核心代码: bool panduan(int col,int i)//判断该情况是否符合情况 { int j,left1,right1; for (j=1;j<col;++j) { left1=col>j?col-j:j-col; right1=i>a[j]?i-a[j]:a[j]-i; if (a[j]==i||left1==right1) return false; } return true; }
核心代码: void work(int col)//进行计算 { int i; if (col>n) { g_max++; return;}//如果放到最后一 行就结束 并加1 for (i=1;i<=n;++i) { f (panduan(col,i)) {a[col]=i;work(col+1);} //能放的情况下继续往下递归 } }
N皇后问题——JAVA实现(源代码)

2011/2012学年第2学期“算法分析与设计”上机报告目录1. 问题描述 (3)2. 算法分析 (3)3. 伪代码 (4)4. 演示程序设计 (5)5. 演示界面 (5)6. 算法实现 (8)7. 总结 (19)8. 参考文献 (20)1.问题描述:N皇后问题(n-queen problem)是一个经典的组合优化问题,也是一个使用回溯法(backtracking)的典型例子。
回溯法是一种系统地搜索问题解的方法。
为了实现回溯,首先需要为为问题定义一个解空间(solution space),其至少包含问题的一个解(可能是最优解)。
我们要从中找出满足问题约束条件的解,即可行解(feasible solution)。
回溯算法一次扩展一个解,在对部分解进行扩展后,检查到目前为止的解是否为问题的一个解,如果是,则输出;否则,检查是否可以继续扩展。
如果可以,则继续扩展;否则,删除最后添加的元素,尝试当前位置是否有另一元素。
若没有合法的扩展方式,则进行回溯(backtrack)。
N皇后问题要求在一个n×n的棋盘上放置n个皇后,且使得每两个皇后之间都不能相互攻击,即它们中的任意两个都不能位于同一行、同一列或者同一对角线上。
这次的任务就是借助GUI实现N皇后问题的动态演示。
我们设定皇后个数在四个到八个之间可选,所选编程语言为JA V A。
2.算法分析:N皇后问题是回溯法的一个经典例子,它的要求就是要找出在n×n的棋盘上放置n个皇后并使其不能相互攻击的所有解。
设X=(x1,x2,…,xn)表示问题的解,,其中xi表示第i皇后放在第i行所在的列数。
由于不存在两个皇后位于同一列上,因此xi互不相同。
设有两个皇后分别位于棋盘( i , j )和( k , l )处,如果两个皇后位于同一对角线上,则表明它们所在的位置应该满足:i – j = k – l或i + j = k + l。
综合这两个等式可得,如果两个皇后位于同一对角线上,那么它们的位置关系一定满足| j – l | = | i – k |。
N皇后问题及答案解

N皇后问题及答案解题⽬在⼀张N∗N的国际象棋棋盘上,放置N个皇后,使得所有皇后都⽆法互相直接攻击得到,(皇后可以直接攻击到她所在的横⾏,竖列,斜⽅向上的棋⼦),现在输⼊⼀个整数N,表⽰在N∗N的棋盘上放N个皇后,请输出共有多少种使得所有皇后都⽆法互相直接攻击得到的⽅案数。
例如下⾯这样的摆法,是4皇后的⼀个解 (1代表有皇后,0代表没有)0 1 0 00 0 0 11 0 0 00 0 1 0输⼊⼀个整数N,代表皇后的个数输出输出⽅案数样例输⼊样例输⼊14样例输⼊28样例输出样例输出12样例输出292⼀、DFS+回溯(1)设已经放好的皇后坐标为(i,j),待放⼊的皇后坐标为(r,c),则它们满⾜以下关系:(1)不同⾏,即 i ≠ r;(2)不同列,即 j ≠ c;(3)不在斜对⾓线上,即 |i-r| ≠ |j-c|.可以在⼀⾏逐列尝试,这样就不⽤考虑(1)了。
#include <iostream>#include <algorithm>#include <cstring>using namespace std;int n, tot = 0;int col[15] = {0}, ans[15] = {0}; //col[i]的值为第i⾏的皇后的列数的值,即j,ans[]数组⽤来存放结果bool check(int c, int r) //检查是否和已经放好的皇后冲突{for (int i = 0; i < r; i++)if (col[i] == c || (abs(col[i] - c) == abs(i - r))) //因为是逐⾏放置,所以只考虑纵向和斜向return false;return true;}void dfs(int r,int m) //在第r⾏放皇后,m表⽰⾏数{if(r==m){ //r==m,即皇后放到最后⼀⾏,满⾜条件,tot++,返回;tot++;return;}for(int c=0;c<m;c++) //在此⾏逐列尝试if(check(c,r)){ //检查是否冲突col[r]=c; //不冲突就在此列放皇后dfs(r+1,m); //转到下⼀⾏继续尝试}}int main(){cin>>n;for (int i = 0; i <= 13; i++) //算出所有N皇后的答案,先打表,不然会超时{memset(col, 0, sizeof(col)); //清空col,准备计算下⼀个N皇后问题tot = 0;dfs(0,i);ans[i] = tot;}cout << ans[n] << endl;return 0;}在上述程序中,dfs()⼀⾏⾏放置皇后,时间复杂度为O(N!);check()判断冲突,时间复杂度为O(N),总的为O(N*N!)!⾮常的⾼。
java-八(N)皇后问题

package datastructure;/*** 八皇后问题,可以扩展到N皇后问题* @author刘冲**/public class EightQueen {/*** 简化操作* 皇后所在行与列之间的关系* queen的索引代表了皇后所在的“列”,数组中存放的皇后的“行”*/private int[] queen; // 用来存放可放的皇后/*** @param r 皇后个数*/public EightQueen(int r){queen = new int[r]; // 用来存放可放的皇后}/*** 检验这个皇后是否不会有冲突* @param r 皇后所在行* @param c 皇后所在列* @param queenList 存皇后的数据* @return如果是安全的返回他true,否则false*/private boolean safeLocation(int r, int c, int[] queenList){ int qr,qc;for(qc = 0; qc < c; qc++){qr = queenList[qc];if(qr == r){return false;}else if(qc == c)return false;else if((qc - qr) == (c - r) ||(qc+qr) == (c+r))return false;}return true;}/*** 放置皇后位置* @param queenList 存放皇后的数组* @param col 下一个皇后所在列* @return*/private boolean placeQueens(int[] queenList, int col){ int row;boolean foundLocation;if(col == queenList.length)foundLocation = true;else{foundLocation = false;row = 0;while(row < queenList.length && !foundLocation){ if(safeLocation(row, col, queenList)){queenList[col] = row;foundLocation = placeQueens(queenList, col+1);if(!foundLocation)row++;}elserow++;}}return foundLocation;}/*** 打印在row放置第一个皇后时的图形,如果没有,则打印没有* @param row 决定第一个皇后放置的行数*/public void printQueen(int row){queen[0] = row;if(placeQueens(queen, 1)){for(int r = 0; r < queen.length; r++){for(int c = 0; c < queen.length; c++){if(queen[c] == r){System.out.print("Q ");}elseSystem.out.print(". ");}System.out.println();}}else{System.out.println("没有");}// 清空queenfor(int i = 0; i < queen.length; i++)queen[i] = 0;}/*** 打印所有的皇后位置情况*/public void printQueen(){for(int i = 0; i < queen.length; i++){printQueen(i);System.out.println("----------------"+(i+1)+"---------------");}}public static void main(String[] args){int r = 8;EightQueen q = new EightQueen(r);q.printQueen();}}运行结果:Q . . . . . . .. . . . . . Q .. . . . Q . . .. . . . . . . Q. Q . . . . . .. . . Q . . . .. . . . . Q . .. . Q . . . . .----------------1---------------. . . . . Q . .Q . . . . . . .. . . . Q . . .. Q . . . . . .. . . . . . . Q. . Q . . . . .. . . . . . Q .----------------2--------------- . Q . . . . . .. . . . . Q . .Q . . . . . . .. . . . . . Q .. . . Q . . . .. . . . . . . Q. . Q . . . . .. . . . Q . . .----------------3--------------- . Q . . . . . .. . . . Q . . .. . . . . . Q .Q . . . . . . .. . Q . . . . .. . . . . . . Q. . . . . Q . .. . . Q . . . .----------------4--------------- . Q . . . . . .. . . . . Q . .. . . . . . . Q. . Q . . . . .Q . . . . . . .. . . Q . . . .. . . . . . Q .. . . . Q . . .----------------5--------------- . Q . . . . . .. . . Q . . . .. . . . . Q . .. . . . . . . Q. . Q . . . . .Q . . . . . . .. . . . . . Q .. . . . Q . . .----------------6--------------- . Q . . . . . .. . . . . . Q .. . Q . . . . .. . . . . Q . .. . . . . . . Q. . . . Q . . .. . . Q . . . .----------------7--------------- . . . Q . . . .. Q . . . . . .. . . . . . Q .. . Q . . . . .. . . . . Q . .. . . . . . . Q. . . . Q . . .Q . . . . . . .----------------8---------------。
N皇后的位运算解法

N皇后的位运算解法⼀、N皇后⼆进制Java代码:public class Solution{int count = 0;public int totalNQueue(n) {if (n < 1) {return n;}//int类型只能表⽰最⼤值为32*32的棋盘,如果⼤于32,则要使⽤long型DFS(0,0,0,0,n);return count;}/*** 使⽤DFS⽅法递归获取每⼀⾏可以放置皇后的位置* row:表⽰棋盘的⾏,最⼤值为n* col:表⽰棋盘的列。
col的int值的右n位⽤来表⽰棋盘的列,若某⼀位⼆进制数为0(不能放置皇后),若为1(可以放置皇后)* pie:表⽰棋盘的左斜列。
pie的int值的右n位⽤来表⽰棋盘的列,若某⼀位⼆进制数为0(不能放置皇后),若为1(可以放置皇后)* na:表⽰棋盘的右斜列。
na的int值的右n位⽤来表⽰棋盘的列,若某⼀位⼆进制数为0(不能放置皇后),若为1(可以放置皇后)* n:表⽰棋盘是n*n的棋盘*/private void DFS(int row, int col, int pie, int na, int n) {//当棋盘的⾏数累加到n时,就表⽰所有的⾏都已⾛完,获取到⼀种放置皇后的⽅法,count加1记录if(row >= n)count++;return;}// 当前⾏可以放置皇后的位置(右n位有⼏个1存在,就表⽰有⼏个可以放置皇后的位置。
0表⽰不能放置)// (col | pie | na):表⽰第⼀⾏所有的位置都为0(后续根据计算值获取)。
使⽤ ~ 取反后,棋盘所有的位置都为1,// 棋盘第⼀⾏所有的位置都可以放置皇后// (1 >> n) - 1:将1的⼆进制左移n位,经过减1后,就将32-n位全部置为0,n为全部置为1;// 由于只需要后n位就可以表⽰棋盘的⼀⾏,所以进⾏ & 运算,就可以保证除了右n位,其余位都为0;int poss = (~(col | pie | na)) & ((1 << n) - 1);// poss不为0,表⽰poss中存在⼆进制位为1的,即存在可以放置皇后的位置while(poss != 0) {//获取⼆进制位中最右边的1,将皇后放在该位置int pos = poss & (-poss);//递归每⼀⾏,处理皇后第⼀⾏在pos位置时,从第2⾏到第n⾏的皇后的摆放位置//na要进⾏⽆符号的右移1位。
实验报告:回溯法求解N皇后问题(Java实现)

实验报告一、实验名称:回溯法求解N皇后问题(Java实现)二、学习知识:回溯法:也称为试探法,它并不考虑问题规模的大小,而是从问题的最明显的最小规模开始逐步求解出可能的答案,并以此慢慢地扩大问题规模,迭代地逼近最终问题的解。
这种迭代类似于穷举并且是试探性的,因为当目前的可能答案被测试出不可能可以获得最终解时,则撤销当前的这一步求解过程,回溯到上一步寻找其他求解路径。
为了能够撤销当前的求解过程,必须保存上一步以来的求解路径,这一点相当重要。
三、问题描述N皇后问题:在一个 N * N 的国际象棋棋盘中,怎样放置 N 个皇后才能使N 个皇后之间不会互相有威胁而共同存在于棋局中,即在 N * N 个格子的棋盘中没有任何两个皇后是在同一行、同一列、同一斜线上。
深度优先遍历的典型案例。
四、求解思路1、求解思路:最容易想到的方法就是有序地从第1列的第 1 行开始,尝试放上一个皇后,然后再尝试第2 列的第几行能够放上一个皇后,如果第 2 列也放置成功,那么就继续放置第 3 列,如果此时第3列没有一行可以放置一个皇后,说明目前为止的尝试是无效的(即不可能得到最终解),那么此时就应该回溯到上一步(即第 2 步),将上一步(第 2 步)所放置的皇后的位置再重新取走放在另一个符合要求的地方…如此尝试性地遍历加上回溯,就可以慢慢地逼近最终解了。
2、需要解决的问题:如何表示一个N * N 方格棋盘能够更有效?怎样测试当前所走的试探路径是否符合要求?这两个问题都需要考虑到使用怎样的数据结构,使用恰当的数据结构有利于简化编程求解问题的难度。
3、我们使用以下的数据结构:int column[col] = row 表示第 col 列的第 row 行放置一个皇后boolean rowExi sts[i] = true 表示第 i 行有皇后boolean a[i] = true 表示右高左低的第 i 条斜线有皇后(按→↓顺序从1~ 2*N -1 依次编号)boolean b[i] = true 表示左高右低的第 i 条斜线有皇后(按→↑顺序从1~ 2*N -1 依次编号)五、算法实现对应这个数据结构的算法实现如下:1.**2. * 回溯法求解N 皇后问题3. * @author haollo yin4. */5.public classN_Quee ns {6.7.// 皇后的个数8. privat e int queens Num = 4;9.10.// column[i] = j表示第 i 列的第 j 行放置一个皇后11. privat e int[] queens = new int[queens Num + 1];12.13.// rowExi sts[i] = true 表示第 i 行有皇后14. privat e boolea n[] rowExi sts = new boolea n[queensNum + 1];15.16.// a[i] = true 表示右高左低的第 i 条斜线有皇后17. privat e boolea n[] a = new boolea n[queens Num * 2];18.19.// b[i] = true 表示左高右低的第 i 条斜线有皇后20. privat e boolea n[] b = new boolea n[queens Num * 2];21.22.// 初始化变量23. privat e void init() {24. for (int i = 0; i < queens Num + 1; i++) {25. rowExi sts[i] = false;26. }27.28. for(int i = 0; i < queens Num * 2; i++) {29. a[i] = b[i] = false;30. }31. }32.33.// 判断该位置是否已经存在一个皇后,存在则返回true34. privat e boolea n isExis ts(int row, int col) {35. return (rowExi sts[row] || a[row + col - 1]|| b[queens Num + col - row]);36. }37.38.// 主方法:测试放置皇后39. public void testin g(int column) {40.41.// 遍历每一行42. for (int row = 1; row < queens Num + 1; row++) {43.// 如果第 row 行第 column列可以放置皇后44. if (!isExis ts(row, column)) {45.// 设置第 row 行第 column列有皇后46. queens[column] = row;47.// 设置以第 row 行第 column列为交叉点的斜线不可放置皇后48. rowExi sts[row] = a[row + column - 1] = b[queens Num + column - row] = true;49.50.// 全部尝试过,打印51. if(column == queens Num) {52. for(int col = 1; col <= queens Num; col++) {53. System.out.print("("+col +"," + queens[col] + ") ");54. }55. System.out.printl n();56. }else {57.// 放置下一列的皇后58. testin g(column + 1);59. }60.// 撤销上一步所放置的皇后,即回溯61. rowExi sts[row] = a[row + column - 1] = b[queens Num + column - row] = false;62. }63. }64. }65.66.//测试67. public static void main(String[] args) {68. N_Quee ns queen= new N_Quee ns();69. queen.init();70.// 从第 1 列开始求解71. queen.testin g(1);72. }73.}六、运行结果当N = 8 时,求解结果如下(注:横坐标为列数,纵坐标为行数):(1,1) (2,5) (3,8) (4,6) (5,3) (6,7) (7,2) (8,4)1.(1,1) (2,6) (3,8) (4,3) (5,7) (6,4) (7,2) (8,5)2.(1,1) (2,7) (3,4) (4,6) (5,8) (6,2) (7,5) (8,3)3.... ...4.... ...5.(1,8) (2,2) (3,4) (4,1) (5,7) (6,5) (7,3) (8,6)6.(1,8) (2,2) (3,5) (4,3) (5,1) (6,7) (7,4) (8,6)7.(1,8) (2,3) (3,1) (4,6) (5,2) (6,5) (7,7) (8,4)8.(1,8) (2,4) (3,1) (4,3) (5,6) (6,2) (7,7) (8,5)当N = 4 时,求解结果如下:1.(1,2) (2,4) (3,1) (4,3)2.(1,3) (2,1) (3,4) (4,2)七、实验小结:1、根据问题选择恰当的数据结构非常重要,就像上面 a 、b 标志数组来表示每一条斜线的编号顺序以及方向都相当重要。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
////////////////////////////////////////画棋盘和皇后的位置 ///////////////////////////////////////
@SuppressWarnings("serial") public class Panel4 extends Applet {
r1.addItemListener(this); r2.addItemListener(this); r3.addItemListener(this); r4.addItemListener(this); r5.addItemListener(this);
button1.addActionListener(this); button2.addActionListener(this); button3.addActionListener(this);
g2.drawLine(i*(240/m)+20,20, i*(240/m)+20,260); g2.drawLine(20, i*(240/m)+20, 260, i*(240/m)+20);
} g2.setColor(Color.blue); for(int i=1;i<=m;i++) {
g2.drawString("Q",30+(X[j][i]-1)*(240/m),10+i*(240/m)); }
cp.add(panel1,BorderLayout.WEST); cp.add(panel4,BorderLayout.CENTER); cp.add(scrollPane1,BorderLayout.EAST);
f.setSize(865,600); f.setVisible(true); f.addWindowListener(new WindowAdapter(){
{ x[k]=x[k]+1;
} if(x[k]<=n)
if(k==n) {
counter++; for(int i=1;i<=n;i++) {
X[a][i]=x[i]; str[a]=str[a]+x[i]+","; } a++; System.out.print("\n"); } else { k=k+1; x[k]=0; } else k=k-1; } return; } ///////////////////////判断皇后位置的合法性/////////////////// public boolean place(int b) { int k=b,i=1; while(i<k) { if(x[i]==x[k] || Math.abs(x[i]-x[k])==Math.abs(i-k)) return(false); i=i+1; }
JButton button1=new JButton("开始演示"); JButton button2=new JButton("暂停"); JButton button3=new JButton("清空");
JSlider slider1=new JSlider(20,100);
javax.swing.Timer timer1; /////////////////////////////////////////////窗口的布局
////////////////////////////////////// public NQueen() { cp.setLayout(new BorderLayout(20,20));
t2.setBorder(BorderFactory.createTitledBorder("解的个数: "));
slider1.setPaintTicks(true); slider1.setMajorTickSpacing(40); slider1.setMinorTickSpacing(20); slider1.setPaintLabels(true);
slider1.setPaintTrack(true); slider1.setSnapToTicks(true); slider1.addChangeListener(this); slider1.setBorder(BorderFactory.createTitledBorder("调节 演示的速度"));
Panel4 panel4=new Panel4();
TextArea t1=new TextArea(30,40); JTextField t2=new JTextField(10);
JRadioButton r1=new JRadioButton("4个"); JRadioButton r2=new JRadioButton("5个"); JRadioButton r3=new JRadioButton("6个"); JRadioButton r4=new JRadioButton("7个"); JRadioButton r5=new JRadioButton("8个");
ButtonGroup buttong1=new ButtonGroup(); buttong1.add(r1); buttong1.add(r2); buttong1.add(r3); buttong1.add(r4); buttong1.add(r5);
panel1.add(panel2); panel1.add(panel3);
实验题目:回溯法—n 皇后问题
班级:信息 112
姓名:孙波
学号:110111213 日期:2014-5-13
一、 实验目的
会用回溯法求解 n 皇后问题,通过实验掌握如何使用回溯法求解问题。
二、 实验要求 用自己熟悉的高级程序设计语言编写程序实现求解 n 皇后问题的回溯算法。 使用剪枝函数来避免不必要的搜索。
return(true); }
//////////////////////////////////////主方法 //////////////////////////////////////////////
/** * @param args */ public static void main(String[] args) {
import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JSlider;
JScrollPane scrollPane1=new JScrollPane(t1); scrollPane1.setBorder(BorderFactory.createTitledBorder(" 展示所有解:"));
JPanel panel1=new JPanel(); panel1.setLayout(new GridLayout(2,1,10,20)); JPanel panel2=new JPanel(); panel2.setLayout(new GridLayout(6,1)); panel2.setBorder(BorderFactory.createTitledBorder("请选择 皇后的个数:")); JPanel panel3=new JPanel(); panel3.setLayout(new GridLayout(4,1,10,10));
timer1=new javax.swing.Timer(slider1.getValue()*25,this);
Hashtable<Integer, JLabel> table=new Hashtable<Integer, JLabel>();
table.put(new Integer(20), new JLabel("快")); table.put(new Integer(100), new JLabel("慢")); slider1.setLabelTable(table);
三、 源程序(带注释)
import java.applet.Applet; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridLayout; import java.awt.TextArea; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Hashtable;