【DS】八皇后问题java代码

只谈情不闲聊 提交于 2020-01-23 15:39:29

八皇后问题简介:八皇后问题,是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯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错误,至今没有查出错误原因,如有读者看出,请不吝赐教

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!