算法篇----八皇后问题

八皇后问题,是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 

算法篇----八皇后问题

  
    
using System;
using System.Collections.Generic;
namespace NET.MST.Thirteenth.Queen
{
/// <summary>
/// 皇后问题内核模块
/// </summary>
public partial class Queens
{
// 棋盘列表,每一项代表一个解的棋盘
private List < int [] > _chessBoard;
// 维度
private int _dimension;
/// <summary>
/// 不允许默认的公共构造方法
/// </summary>
private Queens()
{
}
/// <summary>
/// 构造方法,需要提供维度来构造
/// </summary>
/// <param name="n"> 维度 </param>
public Queens( int n)
{
// 初始化解
_chessBoard = new List < int [] > (n);
// 存储维度
_dimension = n;
// 计算并得到所有解
Calculate();
}
/// <summary>
/// 只读属性,返回维度
/// </summary>
public int Dimension
{
get
{
return _dimension;
}
}
public int [] GetChessBoard( int index)
{
if (_chessBoard.Count <= index ||
index
< 0 )
return null ;
int [] result = new Int32[_dimension];
Array.Copy(_chessBoard[index], result, result.LongLength);
return result;
}
/// <summary>
/// 得到解的数量
/// </summary>
public int GetCount()
{
return _chessBoard.Count;
}
}
/// <summary>
/// 回朔算法的实现
/// </summary>
public partial class Queens
{
/// <summary>
/// 计算入口
/// </summary>
private void Calculate()
{
// 初始化一个棋盘
int [] board = new Int32[_dimension];
// 循环摆放N个皇后,直至第一皇后也需要回朔
for ( int j = 0 ; j < _dimension && j >= 0 ; )
{
// 是否需要回朔的标志
bool found = false ;
// 从第一列摆放到第N列
for ( int i = board[j]; i < _dimension; i ++ )
{
// 检查是否有冲突
if (NoConflict(j, board, i))
{
// 表示没有冲突,实际摆放当前皇后
board[j] = i;
// 如何当前摆放的是最后一个皇后,则表明已经找到一个解
if (j == (_dimension - 1 ))
{
// 复制当前棋盘并且存储这个解
int [] result = new Int32[_dimension];
board.CopyTo(result,
0 );
_chessBoard.Add(result);
// 一个解得到后,就需要回朔来寻找下一个解
found = false ;
}
// 不需要回朔
else
found
= true ;
break ;
}
}
if ( ! found)
{
// 这里回朔,复位当前皇后
board[j] = 0 ;
// 回朔到上一个皇后
j = j - 1 ;
if (j >= 0 )
board[j]
++ ;
}
else
j
++ ;
}
}
/// <summary>
/// 检查当前摆放是否有冲突
/// </summary>
/// <param name="index"> 现在摆放第几个皇后 </param>
/// <param name="board"> 当前棋盘 </param>
/// <param name="val"> 当前尝试摆放的列数 </param>
/// <returns></returns>
private bool NoConflict( int index, int [] board, int val)
{
// 循环检查当前摆放是否和已经摆放的皇后有冲突
// 由于是逐行摆放的,所以不存在两个皇后在同一行的可能,只检查列和斜线
for ( int i = 0 ; i < index; i ++ )
{
if (board[i] == val || // 在同一列上
(index - i) == Math.Abs(board[i] - val)) // 在同一斜线上
return false ;
}
// 检查接触,无冲突
return true ;
}
}
}

你可能感兴趣的:(八皇后)