【DS】八皇后问题java代码

八皇后问题简介:八皇后问题,是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种方法可以解决此问题。

解决方法:回溯算法

Java代码:

 

public class QueenPosition {
	private int x;
	private int y;
	
	public QueenPosition(int row, int column){
		x = row;
		y = column;
	}
	
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
}

 

这个类是用来存储皇后放置在棋盘上的位置的。

以下这个类是解法:

import java.util.ArrayList;

public class EightQueens {
	static ArrayList<QueenPosition> path = new ArrayList<QueenPosition>();
	static int pathCount = 0;//第几种解法,用于打印消息
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		findQueenSolution(0, 0, path);//表明初始化的位置,第一个和第二个参数表明从(0,0)坐标处开始放置,之所以这么写,原因见后面,先放着。path是用来记录路径的
	}
	
    //问题核心 public static void findQueenSolution(int xStart, int yStart, ArrayList<QueenPosition> path){ for(int row = xStart; row < 8 ; row++){//每一行放置一个
               //以下这个判断是为了在回溯过程中,只影响回溯行,而不影响接下去的行 if(row > xStart){ yStart = 0; } //表明是否找到 boolean isFound = false; for(int column = yStart; column < 8 && !isFound; column ++){ //遍历每一列 if(isLegal(row, column, path)){ //如果是合法的(表明可以放置),加入路径 path.add(new QueenPosition(row,column)); isFound = true;//表明找到了! if(row == 7){ //说明是最后一行,此时是可以打印的,同时最后一行也需要回溯,因为可能有多个届 pathCount++; printPath(path); reCall(path); } }else{ //非法情况下 if(column == 7){ //说明是最后一列,此时需要回溯,也就是说上一行摆的位置不对 reCall(path); } } } } }
     //回溯(为了更加清楚的知道这个方法的原理,举一个例子:假设前面四行全部已经放置好皇后,在放置第五行的时候,如果column从0遍历到7都是非法的,那么很明显,此时需要回溯,将第四行从路径中删除,假设第四行原先皇后的摆放位置是(3,4),那么为了不重复放置在此处,需要从(3,5)开始往右边遍历,这也就是为什么需要使用++orginColumn做参数的原因;但是还有可能出现一种情况就是第四行原先的摆放位置是(3,7),此时第四行也不能进行回溯,由此必须也要把它给删掉,回溯到第三行,此时不必担心第一行和第二行,因为这样不符合八皇后的放置规则) public static void reCall(ArrayList<QueenPosition> path){ int pathLength = path.size(); if(pathLength > 0){ //如果还可以回溯(如果已经在第一行,则没办法再去回溯) int orginColumn = path.get(pathLength-1).getY(); path.remove(pathLength-1);//把最后一个除掉 int row = pathLength-1; if(orginColumn == 7 && pathLength > 1){//此时表明上一行也无法回溯 orginColumn = path.get(pathLength-2).getY(); path.remove(pathLength-2); --row; } findQueenSolution(row, ++orginColumn, copyPath(path));//回溯 } } public static boolean isLegal(int x, int y, ArrayList<QueenPosition> path){//检测放置位置是否合法 boolean legal = true; int pathLength = path.size(); for(int index = 0; index < pathLength; index ++){ int xCor = path.get(index).getX(); int yCor = path.get(index).getY(); int xDiff = Math.abs(xCor - x); int yDiff = Math.abs(yCor - y); if((xDiff == yDiff) || xDiff == 0 || yDiff == 0){ //相等表明在对角线上,等于0表明在同一行或者同一列中 legal = false; break; } } return legal; }
     //打印函数 public static void printPath(ArrayList<QueenPosition> path){ System.out.print("第 " + pathCount + "种解法:"); for(int position = 0; position < path.size(); position ++){ System.out.print("(" + path.get(position).getX() + " , " + path.get(position).getY() + ") "); } System.out.println(); }
     //复制arrayList,避免同时操作一个arrayList public static ArrayList<QueenPosition> copyPath(ArrayList<QueenPosition> orginPath){ ArrayList<QueenPosition> copyList = new ArrayList<QueenPosition>(); for(int index = 0; index < orginPath.size(); index ++){ copyList.add(orginPath.get(index)); } return copyList; } }

打印的结果:

 

第 1种解法:(0 , 0)  (1 , 4)  (2 , 7)  (3 , 5)  (4 , 2)  (5 , 6)  (6 , 1)  (7 , 3)  
第 2种解法:(0 , 0)  (1 , 5)  (2 , 7)  (3 , 2)  (4 , 6)  (5 , 3)  (6 , 1)  (7 , 4)  
第 3种解法:(0 , 0)  (1 , 6)  (2 , 3)  (3 , 5)  (4 , 7)  (5 , 1)  (6 , 4)  (7 , 2)  
第 4种解法:(0 , 0)  (1 , 6)  (2 , 4)  (3 , 7)  (4 , 1)  (5 , 3)  (6 , 5)  (7 , 2)  
第 5种解法:(0 , 1)  (1 , 3)  (2 , 5)  (3 , 7)  (4 , 2)  (5 , 0)  (6 , 6)  (7 , 4)  
第 6种解法:(0 , 1)  (1 , 4)  (2 , 6)  (3 , 0)  (4 , 2)  (5 , 7)  (6 , 5)  (7 , 3)  
第 7种解法:(0 , 1)  (1 , 4)  (2 , 6)  (3 , 3)  (4 , 0)  (5 , 7)  (6 , 5)  (7 , 2)  
第 8种解法:(0 , 1)  (1 , 5)  (2 , 0)  (3 , 6)  (4 , 3)  (5 , 7)  (6 , 2)  (7 , 4)  
第 9种解法:(0 , 1)  (1 , 5)  (2 , 7)  (3 , 2)  (4 , 0)  (5 , 3)  (6 , 6)  (7 , 4)  
第 10种解法:(0 , 1)  (1 , 6)  (2 , 2)  (3 , 5)  (4 , 7)  (5 , 4)  (6 , 0)  (7 , 3)  
第 11种解法:(0 , 1)  (1 , 6)  (2 , 4)  (3 , 7)  (4 , 0)  (5 , 3)  (6 , 5)  (7 , 2)  
第 12种解法:(0 , 1)  (1 , 7)  (2 , 5)  (3 , 0)  (4 , 2)  (5 , 4)  (6 , 6)  (7 , 3)  
第 13种解法:(0 , 2)  (1 , 0)  (2 , 6)  (3 , 4)  (4 , 7)  (5 , 1)  (6 , 3)  (7 , 5)  
第 14种解法:(0 , 2)  (1 , 4)  (2 , 1)  (3 , 7)  (4 , 0)  (5 , 6)  (6 , 3)  (7 , 5)  
第 15种解法:(0 , 2)  (1 , 4)  (2 , 1)  (3 , 7)  (4 , 5)  (5 , 3)  (6 , 6)  (7 , 0)  
第 16种解法:(0 , 2)  (1 , 4)  (2 , 6)  (3 , 0)  (4 , 3)  (5 , 1)  (6 , 7)  (7 , 5)  
第 17种解法:(0 , 2)  (1 , 4)  (2 , 7)  (3 , 3)  (4 , 0)  (5 , 6)  (6 , 1)  (7 , 5)  
第 18种解法:(0 , 2)  (1 , 5)  (2 , 1)  (3 , 4)  (4 , 7)  (5 , 0)  (6 , 6)  (7 , 3)  
第 19种解法:(0 , 2)  (1 , 5)  (2 , 1)  (3 , 6)  (4 , 0)  (5 , 3)  (6 , 7)  (7 , 4)  
第 20种解法:(0 , 2)  (1 , 5)  (2 , 1)  (3 , 6)  (4 , 4)  (5 , 0)  (6 , 7)  (7 , 3)  
第 21种解法:(0 , 2)  (1 , 5)  (2 , 3)  (3 , 0)  (4 , 7)  (5 , 4)  (6 , 6)  (7 , 1)  
第 22种解法:(0 , 2)  (1 , 5)  (2 , 3)  (3 , 1)  (4 , 7)  (5 , 4)  (6 , 6)  (7 , 0)  
第 23种解法:(0 , 2)  (1 , 5)  (2 , 7)  (3 , 0)  (4 , 3)  (5 , 6)  (6 , 4)  (7 , 1)  
第 24种解法:(0 , 2)  (1 , 5)  (2 , 7)  (3 , 0)  (4 , 4)  (5 , 6)  (6 , 1)  (7 , 3)  
第 25种解法:(0 , 2)  (1 , 5)  (2 , 7)  (3 , 1)  (4 , 3)  (5 , 0)  (6 , 6)  (7 , 4)  
第 26种解法:(0 , 2)  (1 , 6)  (2 , 1)  (3 , 7)  (4 , 4)  (5 , 0)  (6 , 3)  (7 , 5)  
第 27种解法:(0 , 2)  (1 , 6)  (2 , 1)  (3 , 7)  (4 , 5)  (5 , 3)  (6 , 0)  (7 , 4)  
第 28种解法:(0 , 2)  (1 , 7)  (2 , 3)  (3 , 6)  (4 , 0)  (5 , 5)  (6 , 1)  (7 , 4)  
第 29种解法:(0 , 3)  (1 , 0)  (2 , 4)  (3 , 7)  (4 , 1)  (5 , 6)  (6 , 2)  (7 , 5)  
第 30种解法:(0 , 3)  (1 , 0)  (2 , 4)  (3 , 7)  (4 , 5)  (5 , 2)  (6 , 6)  (7 , 1)  
第 31种解法:(0 , 3)  (1 , 1)  (2 , 4)  (3 , 7)  (4 , 5)  (5 , 0)  (6 , 2)  (7 , 6)  
第 32种解法:(0 , 3)  (1 , 1)  (2 , 6)  (3 , 2)  (4 , 5)  (5 , 7)  (6 , 0)  (7 , 4)  
第 33种解法:(0 , 3)  (1 , 1)  (2 , 6)  (3 , 2)  (4 , 5)  (5 , 7)  (6 , 4)  (7 , 0)  
第 34种解法:(0 , 3)  (1 , 1)  (2 , 6)  (3 , 4)  (4 , 0)  (5 , 7)  (6 , 5)  (7 , 2)  
第 35种解法:(0 , 3)  (1 , 1)  (2 , 7)  (3 , 4)  (4 , 6)  (5 , 0)  (6 , 2)  (7 , 5)  
第 36种解法:(0 , 3)  (1 , 1)  (2 , 7)  (3 , 5)  (4 , 0)  (5 , 2)  (6 , 4)  (7 , 6)  
第 37种解法:(0 , 3)  (1 , 5)  (2 , 0)  (3 , 4)  (4 , 1)  (5 , 7)  (6 , 2)  (7 , 6)  
第 38种解法:(0 , 3)  (1 , 5)  (2 , 7)  (3 , 1)  (4 , 6)  (5 , 0)  (6 , 2)  (7 , 4)  
第 39种解法:(0 , 3)  (1 , 5)  (2 , 7)  (3 , 2)  (4 , 0)  (5 , 6)  (6 , 4)  (7 , 1)  
第 40种解法:(0 , 3)  (1 , 6)  (2 , 0)  (3 , 7)  (4 , 4)  (5 , 1)  (6 , 5)  (7 , 2)  
第 41种解法:(0 , 3)  (1 , 6)  (2 , 2)  (3 , 7)  (4 , 1)  (5 , 4)  (6 , 0)  (7 , 5)  
第 42种解法:(0 , 3)  (1 , 6)  (2 , 4)  (3 , 1)  (4 , 5)  (5 , 0)  (6 , 2)  (7 , 7)  
第 43种解法:(0 , 3)  (1 , 6)  (2 , 4)  (3 , 2)  (4 , 0)  (5 , 5)  (6 , 7)  (7 , 1)  
第 44种解法:(0 , 3)  (1 , 7)  (2 , 0)  (3 , 2)  (4 , 5)  (5 , 1)  (6 , 6)  (7 , 4)  
第 45种解法:(0 , 3)  (1 , 7)  (2 , 0)  (3 , 4)  (4 , 6)  (5 , 1)  (6 , 5)  (7 , 2)  
第 46种解法:(0 , 3)  (1 , 7)  (2 , 4)  (3 , 2)  (4 , 0)  (5 , 6)  (6 , 1)  (7 , 5)  
第 47种解法:(0 , 4)  (1 , 0)  (2 , 3)  (3 , 5)  (4 , 7)  (5 , 1)  (6 , 6)  (7 , 2)  
第 48种解法:(0 , 4)  (1 , 0)  (2 , 7)  (3 , 3)  (4 , 1)  (5 , 6)  (6 , 2)  (7 , 5)  
第 49种解法:(0 , 4)  (1 , 0)  (2 , 7)  (3 , 5)  (4 , 2)  (5 , 6)  (6 , 1)  (7 , 3)  
第 50种解法:(0 , 4)  (1 , 1)  (2 , 3)  (3 , 5)  (4 , 7)  (5 , 2)  (6 , 0)  (7 , 6)  
第 51种解法:(0 , 4)  (1 , 1)  (2 , 3)  (3 , 6)  (4 , 2)  (5 , 7)  (6 , 5)  (7 , 0)  
第 52种解法:(0 , 4)  (1 , 1)  (2 , 5)  (3 , 0)  (4 , 6)  (5 , 3)  (6 , 7)  (7 , 2)  
第 53种解法:(0 , 4)  (1 , 1)  (2 , 7)  (3 , 0)  (4 , 3)  (5 , 6)  (6 , 2)  (7 , 5)  
第 54种解法:(0 , 4)  (1 , 2)  (2 , 0)  (3 , 5)  (4 , 7)  (5 , 1)  (6 , 3)  (7 , 6)  
第 55种解法:(0 , 4)  (1 , 2)  (2 , 0)  (3 , 6)  (4 , 1)  (5 , 7)  (6 , 5)  (7 , 3)  
第 56种解法:(0 , 4)  (1 , 2)  (2 , 7)  (3 , 3)  (4 , 6)  (5 , 0)  (6 , 5)  (7 , 1)  
第 57种解法:(0 , 4)  (1 , 6)  (2 , 0)  (3 , 2)  (4 , 7)  (5 , 5)  (6 , 3)  (7 , 1)  
第 58种解法:(0 , 4)  (1 , 6)  (2 , 0)  (3 , 3)  (4 , 1)  (5 , 7)  (6 , 5)  (7 , 2)  
第 59种解法:(0 , 4)  (1 , 6)  (2 , 1)  (3 , 3)  (4 , 7)  (5 , 0)  (6 , 2)  (7 , 5)  
第 60种解法:(0 , 4)  (1 , 6)  (2 , 1)  (3 , 5)  (4 , 2)  (5 , 0)  (6 , 3)  (7 , 7)  
第 61种解法:(0 , 4)  (1 , 6)  (2 , 1)  (3 , 5)  (4 , 2)  (5 , 0)  (6 , 7)  (7 , 3)  
第 62种解法:(0 , 4)  (1 , 6)  (2 , 3)  (3 , 0)  (4 , 2)  (5 , 7)  (6 , 5)  (7 , 1)  
第 63种解法:(0 , 4)  (1 , 7)  (2 , 3)  (3 , 0)  (4 , 2)  (5 , 5)  (6 , 1)  (7 , 6)  
第 64种解法:(0 , 4)  (1 , 7)  (2 , 3)  (3 , 0)  (4 , 6)  (5 , 1)  (6 , 5)  (7 , 2)  
第 65种解法:(0 , 5)  (1 , 0)  (2 , 4)  (3 , 1)  (4 , 7)  (5 , 2)  (6 , 6)  (7 , 3)  
第 66种解法:(0 , 5)  (1 , 1)  (2 , 6)  (3 , 0)  (4 , 2)  (5 , 4)  (6 , 7)  (7 , 3)  
第 67种解法:(0 , 5)  (1 , 1)  (2 , 6)  (3 , 0)  (4 , 3)  (5 , 7)  (6 , 4)  (7 , 2)  
第 68种解法:(0 , 5)  (1 , 2)  (2 , 0)  (3 , 6)  (4 , 4)  (5 , 7)  (6 , 1)  (7 , 3)  
第 69种解法:(0 , 5)  (1 , 2)  (2 , 0)  (3 , 7)  (4 , 3)  (5 , 1)  (6 , 6)  (7 , 4)  
第 70种解法:(0 , 5)  (1 , 2)  (2 , 0)  (3 , 7)  (4 , 4)  (5 , 1)  (6 , 3)  (7 , 6)  
第 71种解法:(0 , 5)  (1 , 2)  (2 , 4)  (3 , 6)  (4 , 0)  (5 , 3)  (6 , 1)  (7 , 7)  
第 72种解法:(0 , 5)  (1 , 2)  (2 , 4)  (3 , 7)  (4 , 0)  (5 , 3)  (6 , 1)  (7 , 6)  
第 73种解法:(0 , 5)  (1 , 2)  (2 , 6)  (3 , 1)  (4 , 3)  (5 , 7)  (6 , 0)  (7 , 4)  
第 74种解法:(0 , 5)  (1 , 2)  (2 , 6)  (3 , 1)  (4 , 7)  (5 , 4)  (6 , 0)  (7 , 3)  
第 75种解法:(0 , 5)  (1 , 2)  (2 , 6)  (3 , 3)  (4 , 0)  (5 , 7)  (6 , 1)  (7 , 4)  
第 76种解法:(0 , 5)  (1 , 3)  (2 , 0)  (3 , 4)  (4 , 7)  (5 , 1)  (6 , 6)  (7 , 2)  
第 77种解法:(0 , 5)  (1 , 3)  (2 , 1)  (3 , 7)  (4 , 4)  (5 , 6)  (6 , 0)  (7 , 2)  
第 78种解法:(0 , 5)  (1 , 3)  (2 , 6)  (3 , 0)  (4 , 2)  (5 , 4)  (6 , 1)  (7 , 7)  
第 79种解法:(0 , 5)  (1 , 3)  (2 , 6)  (3 , 0)  (4 , 7)  (5 , 1)  (6 , 4)  (7 , 2)  
第 80种解法:(0 , 5)  (1 , 7)  (2 , 1)  (3 , 3)  (4 , 0)  (5 , 6)  (6 , 4)  (7 , 2)  
第 81种解法:(0 , 6)  (1 , 0)  (2 , 2)  (3 , 7)  (4 , 5)  (5 , 3)  (6 , 1)  (7 , 4)  
第 82种解法:(0 , 6)  (1 , 1)  (2 , 3)  (3 , 0)  (4 , 7)  (5 , 4)  (6 , 2)  (7 , 5)  
第 83种解法:(0 , 6)  (1 , 1)  (2 , 5)  (3 , 2)  (4 , 0)  (5 , 3)  (6 , 7)  (7 , 4)  
第 84种解法:(0 , 6)  (1 , 2)  (2 , 0)  (3 , 5)  (4 , 7)  (5 , 4)  (6 , 1)  (7 , 3)  
第 85种解法:(0 , 6)  (1 , 2)  (2 , 7)  (3 , 1)  (4 , 4)  (5 , 0)  (6 , 5)  (7 , 3)  
第 86种解法:(0 , 6)  (1 , 3)  (2 , 1)  (3 , 4)  (4 , 7)  (5 , 0)  (6 , 2)  (7 , 5)  
第 87种解法:(0 , 6)  (1 , 3)  (2 , 1)  (3 , 7)  (4 , 5)  (5 , 0)  (6 , 2)  (7 , 4)  
第 88种解法:(0 , 6)  (1 , 4)  (2 , 2)  (3 , 0)  (4 , 5)  (5 , 7)  (6 , 1)  (7 , 3)  
第 89种解法:(0 , 7)  (1 , 1)  (2 , 3)  (3 , 0)  (4 , 6)  (5 , 4)  (6 , 2)  (7 , 5)  
第 90种解法:(0 , 7)  (1 , 1)  (2 , 4)  (3 , 2)  (4 , 0)  (5 , 6)  (6 , 3)  (7 , 5)  
第 91种解法:(0 , 7)  (1 , 2)  (2 , 0)  (3 , 5)  (4 , 1)  (5 , 4)  (6 , 6)  (7 , 3)  
第 92种解法:(0 , 7)  (1 , 3)  (2 , 0)  (3 , 2)  (4 , 5)  (5 , 1)  (6 , 6)  (7 , 4) 

 

  

备注:运行的时候,会出现第93,94,95种解,和前面的5,6,7是重复的,并且会发生StackOverflowError错误,至今没有查出错误原因,如有读者看出,请不吝赐教

 

你可能感兴趣的:(java)