`

回溯法应用之n皇后问题

 
阅读更多
在n行n列的棋盘上,如果两个皇后位于棋盘上的同一行或者同一列或者同一对角线上,则称他们为互相攻击。现要求找出使n元棋盘上的n个皇后互不攻击的所有布局,即是n皇后问题

package 数据结构及算法.回溯法应用之n皇后问题;

import java.util.Iterator;

import 数据结构及算法.回溯法.Application;
import 数据结构及算法.回溯法.Position;

public class Queen implements Application{
    private int[][]grid;
    private int[][]path;
    public Queen(int n){
    	this.grid=new int[n][n];
    	this.path=new int[n][2];
    	for(int i=0;i<n;i++){
    		for(int j=0;j<n;j++){
    			this.grid[i][j]=0;
    		}
    	}
    }
	@Override
	public boolean valid(Position pos) {
		if(this.grid[pos.getRow()][pos.getColumn()]==0)
		return true;
		return false;
	}

	@Override
	public void record(Position pos) {
		for(int i=0;i<this.grid.length;i++){
			if(i!=pos.getColumn())
			    this.grid[pos.getRow()][i]+=1;//横
			if(i!=pos.getRow())
				this.grid[i][pos.getColumn()]+=1;//竖		
		}
		int x=pos.getRow()-1;
		int y=pos.getColumn()-1;
		while(x>=0&&y>=0){//左上
			this.grid[x][y]+=1;
			x--;
			y--;
		}
		x=pos.getRow()+1;
		y=pos.getColumn()-1;
		while(x<this.grid.length&&y>=0){//左下
			this.grid[x][y]+=1;
			x++;
			y--;
		}
		x=pos.getRow()-1;
		y=pos.getColumn()+1;
		while(y<this.grid.length&&x>=0){//右上
			this.grid[x][y]+=1;
			x--;
			y++;
		}
		x=pos.getRow()+1;
		y=pos.getColumn()+1;
		while(x<this.grid.length&&y<this.grid.length){//右下
			this.grid[x][y]+=1;
			x++;
			y++;
		}
		this.grid[pos.getRow()][pos.getColumn()]+=2*this.grid.length;
	}

	@Override
	public boolean done(Position pos) {
		if(pos.getRow()==this.grid.length-1)
			return true;
		return false;
	}

	@Override
	public void undo(Position pos) {
		for(int i=0;i<this.grid.length;i++){
			if(i!=pos.getColumn())
			    this.grid[pos.getRow()][i]-=1;//横
			if(i!=pos.getRow())
				this.grid[i][pos.getColumn()]-=1;//竖		
		}
		int x=pos.getRow()-1;
		int y=pos.getColumn()-1;
		while(x>=0&&y>=0){//左上
			this.grid[x][y]-=1;
			x--;
			y--;
		}
		x=pos.getRow()+1;
		y=pos.getColumn()-1;
		while(x<this.grid.length&&y>=0){//左下
			this.grid[x][y]-=1;
			x++;
			y--;
		}
		x=pos.getRow()-1;
		y=pos.getColumn()+1;
		while(y<this.grid.length&&x>=0){//右上
			this.grid[x][y]-=1;
			x--;
			y++;
		}
		x=pos.getRow()+1;
		y=pos.getColumn()+1;
		while(x<this.grid.length&&y<this.grid.length){//右下
			this.grid[x][y]-=1;
			x++;
			y++;
		}
		this.grid[pos.getRow()][pos.getColumn()]-=2*this.grid.length;
	}
	
	public String toString(){
		String result="";
    	for(int i=0;i<this.grid.length;i++){
    		for(int j=0;j<this.grid[0].length;j++){
    			if(this.grid[i][j]==2*this.grid.length)
    				result+="*"+" ";
    			else
    				result+=this.grid[i][j]+" ";
    			
    		}
    		result+="\n";
    	}
    	return result;
    }

	@Override
	public Iterator iterator(Position pos) {
		
		return new QueenIterator(pos,this.grid.length);
	}
    private class QueenIterator implements Iterator{
    	private int size;
    	private int count=0;
    	private int row;
    	//private int col;
        public QueenIterator(Position pos,int queenGridLength){
        	 this.row=pos.getRow();
        	 //this.col=pos.getColumn();
        	 this.size=queenGridLength;
        }
		@Override
		public boolean hasNext() {
			return count<this.size;
		}

		@Override
		public Object next() {
			Position nextPos=new Position(this.row+1,count); 
			count++;
			return nextPos;
		}

		@Override
		public void remove() {
			throw new UnsupportedOperationException();
		}
    	
    }
}

初始情况是整个棋盘每个位置初始值为0,public boolean valid(Position pos)中判断为0 有效
在public void record(Position pos)中我让该位置为中心的横竖斜的方向上每个位置之加1,该位置加2*this.grid.length;
public void undo(Position pos),撤销时与上是逆过程;

private class QueenIterator implements Iterator为内部类,记录某位置的下一行可选位置,



一下是测试程序:
package 数据结构及算法.回溯法应用之n皇后问题;

import java.util.Iterator;
import java.util.Scanner;

import 数据结构及算法.回溯法.Application;
import 数据结构及算法.回溯法.BackTrack;
import 数据结构及算法.回溯法.Position;


public class QueenTest {
	
    private int n;
    public QueenTest(){
    	Scanner sc=new Scanner(System.in);
    	String  prompt="请输入皇后的大于3的维数!";
    	System.out.println(prompt);
    	this.n=sc.nextInt();
    	pocessInput();
    }
	
	public void pocessInput() {
		
		Application app=new Queen(n);
		BackTrack backTrack=new BackTrack(app);
		
		println("开始为:");
		println(app.toString());
		Position pos=new Position(-1,0);
		Iterator itr=app.iterator(pos);
		int count=0;
		while(itr.hasNext()){
			Position startPosition=(Position) itr.next();
			app.record(startPosition);
			if(backTrack.tryToSolve(startPosition)){
				println("success");
				count++;
				println("第"+count+"个满足的为:");
				println(app.toString());
				app=new Queen(this.n);
				backTrack=new BackTrack(app);
			}
			else{
				app=new Queen(this.n);
				backTrack=new BackTrack(app);
				println("failure!");
			}
			
		}
		
	}
	
	public void println(String s){
		System.out.println(s);
	}
	public static void main(String[]args){
		new QueenTest();
	}
}


测试时可找到从第一排每个位置开始的可能的n皇后结果,还有什么不妥的地方,欢迎拍砖
分享到:
评论

相关推荐

    黑板风格,管道风格,调用返回风格,回溯法等解决N皇后问题

    N皇后的实现方法,回溯法,非递归法,黑板风格,管道风格。等等吧。

    回溯算法n皇后问题

    应用回溯法,当可以放置皇后时就继续到下一行,不行的话就返回到第一行,重新检验要放的列数,如此反复,直到将所有解解出。 也就是对于N×N的棋盘,选择出N个符合i!=r∧j!=s∧|i-r|!=|j-s|∨(i+r)!=(j+s)的点的...

    n皇后问题(回溯法)C++实现

    希望能对大家应用回溯法有帮助!

    n皇后问题是递归和回溯法的一个典型应用[参考].pdf

    n皇后问题是递归和回溯法的一个典型应用[参考].pdf

    N皇后问题java实现

    用java语言实现N皇后问题: 基本思路:X(j)表示一个解的空间,j表示行数,里面的值表示可以放置在的列数,抽象约束条件得到能放置一个皇后的约束条件(1)X(i)!=X(k);(2)abs(X(i)-X(k))!=abs(i-k)。应用回溯法,当可以...

    N皇后问题 C程序设计

    N皇后问题 回溯算法 1.问题描述:在一个N*N的棋盘上放置N个皇后,且使得每两个之间不能...应用回溯法,当可以放置皇后时就继续到下一行,不行的话就返回到第一行,重新检验要放的列数,如此反复,直到将所有解解出。

    论文研究-求解图同构的判定算法.pdf

    采用自然数和二进制互换的编码方式,应用N皇后的约束条件构造适应度函数,保证了算法的全局收敛性。通过与回溯法和相关遗传算法比较,实验证实了该方法应用于求解N皇后问题,具有良好的搜索效率和求解质量。

    深入N皇后问题的两个最高效算法的详解

    一、 求解N皇后问题是算法中回溯法应用的一个经典案例回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。在现实中,有很多...

    八皇后问题的两个高效的算法

    一、 求解八皇后问题是算法中回溯法应用的一个经典案例 回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。 在现实中,有...

    树型状态空间问题的回溯法 C语言编程模式 (2013年)

    针对树型状态空间的回溯提出了一个 C语言编程模式,并利用 n皇后、 0-1背包这2个典型问题验证了该模式的正确性。该模式有助于提升对回溯法解题的理解,提高回溯法实 现的可复用性,扩大回溯法的应用范围。

    算法设计与分析.rar

    回溯法 内容:用回溯法求解N皇后问题。 要求:掌握回溯法通过搜索状态空间树中的每个问题状态来求解一个或全部可行解的算法思想;能够分析问题的具体特征并设计算法,运用回溯法的算法思想求解实际问题。 密码算法...

    易语言5.0自带源代码[经典数学算法集.rar]

    58.八皇后问题(回溯法) 59.求N阶幻方 60.计算分数的精确值 61.找零钱 62.求一元二次方程的根(公式法) 63.比赛日程(分治法) 64.两个有序数组的合并 65.统计投色子(2个)的结果 66.12小球问题 67.改进冒泡排序法 68....

    几个用C++实现的算法的实例

    其中包括:最小生成树、最大相同字符子串、最大公约数、杨辉三角、验证n是不是素数、贪心算法在背包问题中的应用、日期计算星期几、去除数组中的重复数字、求素数算法、n 皇后问题(回溯法)、组合问题、希尔排序、...

    《妙趣横生的算法(C语言实现)》(杨峰 编著)

    3.6 回溯法 3.6.1 基本概念 3.6.2 四皇后问题求解 3.7 数值概率算法 3.7.1 基本概念 3.7.2 计算定积分 第2部分 编程实例解析 第4章 编程基本功 4.1 字符类型统计器 4.2 计算字符的ASCII码 4.3 嵌套if.else语句的妙...

    C#经验技巧宝典1-5

    0075 用回溯法找出n个自然数中取r个数的全排列 55 0076 约瑟夫环问题 56 0077 猴子选大王 57 0078 如何判断IP是否正确 57 0079 如何将小写金额转换为大写金额 57 0080 统计文本字数 58 0081 文本...

    史上最全经典数据结构算法c语言实现代码合集

    N皇后问题回溯算法.txt ping.txt re.txt source.txt winsock2.txt ww.txt 万年历.txt 万年历的算法 .txt 乘方函数桃子猴.txt 乘法矩阵.txt 二分查找1.txt 二分查找2.txt 二叉排序树.txt 二叉树.txt ...

    C++数据抽象和问题求解(第6版).[美]Frank M. Carrano(带详细书签).pdf

    ◆ 诠释了ADT的主要应用,如查找航班图、事件驱动的模拟和八皇后问题 ◆ 大部分章节中的例子都使用了标准模板库(STL) ◆ 介绍了递归 ◆ 附录中提供了基本的C++语法,以帮助学生从其他语言转换为C++ 第1章 数据...

    ACM程序设计培训教程

     4.2 回溯法解决背包问题………………………………………………………………81  〖案例2〗0/1背包…………………………………………………………………81  4.3 遗传算法解决背包问题………………………………...

    数据结构与算法.xmind

    n皇后问题 动态规划Dynamic Planning 应用 求最长公共子序列LCS 矩阵连乘问题 爬楼梯问题 找零问题 0-1背包问题 分治算法Divide and Conquer 应用:归并排序 其它 Rabin ...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar

    他是我国计算机普及和高校计算机基础教育开拓者之一,现任全国高等院校计算机基础教育研究会会长、教育部全国计算机应用技术证书考试委员会主任委员。 谭浩强教授创造了3个世界纪录:(1)20年来他(及和他人合作)...

Global site tag (gtag.js) - Google Analytics