回溯法实例―n皇后算法 (java实现)

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

Math.abs(k-j)==Math.abs(x[j]-x[k])||(x[j]==x[k])//满足此条,说明不符合条件,即处在同一行或同一列或同一斜线
import java.util.Scanner;

public class BackTrack {
	public static void main(String [] agrs){
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入n:");
		int n = sc.nextInt();
		System.out.println(n+"皇后的解决方案有"+track(n)+"种");
	}
	public static long track(int n){
		Queen X = new Queen();//使用递归方法
		Queen Y = new Queen();//使用迭代方法
		X.n = n;
		X.sum = 0;
		Y.n = n;
		Y.sum = 0;
		int[] arr = new int[n+1];
		for(int i=0;i<=n;i++){
			arr[i]=0;
		}
		X.x = arr;
		Y.x = arr;
		long startTime = System.currentTimeMillis();
		X.backTrack(1);
		long endTime = System.currentTimeMillis();
		System.out.println("使用递归方法运行时间:"+(endTime-startTime)+"ms");
		for(int i=0;i<=n;i++){
			Y.x[i]=0;
		}
		startTime = System.currentTimeMillis();
		Y.whileBackTrack();
		endTime = System.currentTimeMillis();
		System.out.println("使用循环方法运行时间:"+(endTime-startTime)+"ms");
		return X.sum;
	}
}
class Queen{
	public int n; //皇后个数
	public int[] x;//当前解    index代表行  x[index]代表列
	public long sum;//当前已找到的可行方案数

	private boolean Place(int k){//检查在第k行的可行性
		for(int j=1;j<k;j++){
			if(Math.abs(k-j)==Math.abs(x[j]-x[k])||(x[j]==x[k]))return false;//说明不符合条件
		}
		return true;//说明符合条件
	}
	public void backTrack(int t){//递归方法
		if(t>n) {//当其抵达叶子结点的时候,即所有层都搜索完毕
			sum++;//可行方案数+1
			printWay();//打印出当前的解
		}
		else{
			for(int i=1;i<=n;i++){//每次循环右移一列
				x[t] = i;
				if(Place(t))backTrack(t+1);//深度优先递归地对子树搜索
			}
		}
	}
	public long whileBackTrack(){//循环方法
		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){//退出while循环时没有越界
				if(k==n)sum++;//抵达最后一行,可行方案数+1
				else{
					k++;//下移一行
					x[k] = 0;//将初值赋值为0
				}
			}else k--;//说明这个方法行不通,向上退一行
		}
		return sum;
	}
	public void printWay(){
		for(int i=1;i<=n;i++){
			System.out.print("("+i+","+x[i]+") ");
		}
		System.out.println();
	}
}

运行截图:

时间: 2024-11-12 21:17:11

回溯法实例―n皇后算法 (java实现)的相关文章

ACM:回溯法,八皇后问题,素数环

(一)八皇后问题 (1)回溯法 #include <iostream> #include <string> #define MAXN 100 using namespace std; int tot = 0, n = 8; int C[MAXN]; void search(int cur) { if(cur == n) ++tot; //递归边界,只要走到了这里,所有皇后必然不冲突 else for(int i = 0; i < n; ++i) { int ok = 1; C

回溯法求解N皇后问题

问题描述: 在n*n格的棋盘上放置彼此不受攻击的n个皇后(按照国际象棋的规则),即任意两个皇后不能处在同一行或同一列或同一斜线上. 实现: /* *回溯法,N皇后问题 *author: [email protected] */ #include <iostream> #include <vector> #include <cmath> using namespace std; struct Point{ Point(int _x, int _y): x(_x), y(_

算法-回溯法初探-n皇后问题

问题描述: 这周的数据结构作业要求写一个程序判断输入为n的所有皇后的情况, 皇后大致就是在一个n*n的棋盘上所有不同行列及不同对角线的格子排列 提示用书本上求解迷宫时用到的回溯法,也就是用到一个栈来保存当前满足的皇后,若进行不下去则回溯 采用C语言实现 代码: 1,文件 BetterQueen.h 里面主要定义了一些程序要用到的数据结构和函数接口 #ifndef BETTERQUEEN_H_INCLUDED #define BETTERQUEEN_H_INCLUDED #include <std

【基础算法】回溯法与八皇后问题

在国际象棋中,皇后是最强大的一枚棋子,可以吃掉与其在同一行.列和斜线的敌方棋子.比中国象棋里的车强几百倍,比她那没用的老公更是强的飞起(国王只能前后左右斜线走一格).上图右边高大的棋子即为皇后. 八皇后问题是这样一个问题:将八个皇后摆在一张8*8的国际象棋棋盘上,使每个皇后都无法吃掉别的皇后,一共有多少种摆法?此问题在1848年由棋手马克斯·贝瑟尔提出,岂止是有年头,简直就是有年头,82年的拉菲分分钟被秒的渣都不剩. 八皇后问题是典型的回溯法解决的问题,我们以这个问题为例介绍回溯法. 所谓回溯法

每天刷个算法题20160519:回溯法解八皇后

版权所有.所有权利保留. 欢迎转载,转载时请注明出处: http://blog.csdn.net/xiaofei_it/article/details/51502622 为了防止思维僵化,每天刷个算法题.已经刷了几天了,现在发点代码. 我已经建了一个开源项目,每天的题目都在里面: https://github.com/Xiaofei-it/Algorithms 绝大部分算法都是我自己写的,没有参考网上通用代码.读者可能会觉得有的代码晦涩难懂,因为那是我自己的理解. 最近几天都是在写一些原来的东西

回溯法求解八皇后问题---(初步、未优化)

首先介绍一下回溯算法: 定义来自<百度百科>......名字着很高大上,实际上就是试探法,逐步试错找到最终的可行解. 重要的一点是解空间通常是在搜索可行解过程中动态产生的,所以程序中通常利用到递归的算法,如后面介绍的八皇后问题.这点区别与于前段时间所写的模拟退火算法,模拟退火是首先确定解空间,然后以一定的概率接受当前发现的次优解,从而有更大的可能避免局部最优而得到全局最优. 简单介绍一下八皇后问题: 在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或

两道关于回溯法,分支限界法的算法题

1.最小重量机器设计问题:设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得.设 wij    是从供应商j处购得的部件 i 的重量, cij 是相应的价格.试设计一个算法,给出总价格不超过 c 的最小重量机器设计. 方法一:回溯法设计: import static org.junit.Assert.*; import java.util.Scanner; import org.junit.Test; public class 最小重量机器 { /* * 3 3 * 3 2 1

【回溯法】八皇后问题(递归和非递归)

先贴代码,分递归回溯法和非递归回溯法 递归回溯法,代码如下: // test.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> #include <stdio.h> using namespace std; int a[9] = {0}; int n = 8; int count = 0; bool check

暴力回溯法 解八皇后

国际象棋 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. public class _8Queen { //回溯法,暴力解8皇后 private static int ways = 0; //返回解法个数 public static int f8queen() { int[][] board = new int