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

  首先介绍一下回溯算法:

  

  定义来自《百度百科》......名字着很高大上,实际上就是试探法,逐步试错找到最终的可行解。

  重要的一点是解空间通常是在搜索可行解过程中动态产生的,所以程序中通常利用到递归的算法,如后面介绍的八皇后问题。这点区别与于前段时间所写的模拟退火算法,模拟退火是首先确定解空间,然后以一定的概率接受当前发现的次优解,从而有更大的可能避免局部最优而得到全局最优。

  

  

  简单介绍一下八皇后问题:

  在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 

  下面是用回溯法写的java程序,效率很低,可以用多种方法进行优化,以后补充(希望我会进行优化更新博客.........)

public class EightQueen {
	private int[] resultRange;
	private int rangeNum=0;
	public EightQueen(int num)
	{
		this.resultRange=new int[num];
	}
	
	public static void main(String[] args)
	{
		long startMillis=System.currentTimeMillis();
		
		EightQueen eQueen=new EightQueen(8);
		eQueen.rangeQueen(0);
		
		long endMillis=System.currentTimeMillis();
		
		System.out.println("共"+eQueen.rangeNum+"种方案");
		System.out.println("共消耗时间:"+(endMillis-startMillis));	
	}
	
	//回溯法-----放置皇后
	private void rangeQueen(int num) {
		if(num>=resultRange.length)
		{
			printResult();
			rangeNum++;
			return;
		}
		
		for(int i=0;i<resultRange.length;i++)
		{
			resultRange[num]=i;
			if(checkQueen(num))
			{
				rangeQueen(num+1);//迭代求解
			}
		}
	}

	//检查是否存在同列或同斜线的皇后
	private boolean checkQueen(int n) {
		// TODO Auto-generated method stub
		for(int i=0;i<n;i++)
		{
			if(resultRange[n]==resultRange[i] || Math.abs(n-i)==Math.abs(resultRange[n]-resultRange[i]))
			{
				return false;
			}
			
		}
		return true;
	}
	
	//打印出每一种方案以及最终的方案数
	private void printResult() {
		
		System.out.println("第"+(rangeNum+1)+"种方案");
		for(int i=0;i<resultRange.length;i++)
		{
			
			for(int j=0;j<resultRange.length;j++)
			{
				if(j==resultRange[i])
				{
					System.out.print("*  ");					
				}
				else {
					System.out.print(0+"  ");
				}
			}		
			System.out.println();
		}
		System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
	}	
}

  运行结果截图:

 

posted @ 2018-05-22 18:40  Vic07  阅读(858)  评论(0编辑  收藏  举报