回溯算法——解决n皇后问题

所谓回溯(backtracking)是通过系统地搜索求解问题的方法。这种方法适用于类似于八皇后这样的问题:求得问题的一个解比较困难,但是检查一个棋局是否构成解很容易。

不多说,放上n皇后的回溯问题代码:

//Queens.h
#define Queens_H
#ifndef Queeens_H

#include <vector>
using namespace std;

class Queens
{
public:
	Queens(int size);   //构造规模为n行n列的空棋盘
	bool is_solved() const;  //当前棋盘构成解
	void print() const;   //输出当前棋盘
	bool unguarded(int col) const;  //在(count,col)处放置皇后没有冲突
	void insert(int col);   //在(count,col)处放置皇后
	void remove(int col);  //删除(count,col)处放置的皇后
	void solve_from(Queens &configuration);   //n皇后问题回溯算法
	int board_size;    //棋盘规模
private:
	int count;   //当前棋盘上皇后个数
	vector<vector<bool> > queen_square;   
};

#endif

 

//Queens.cpp
#include "Queens.h"
#include <vector>
#include <iostream>
using namespace std;

Queens::Queens(int size)
{
	queen_square.resize(size);
	int i;
	for(i = 0;i < queen_square.size();i++)
	{
		queen_square[i].resize(size);
	}
	board_size = size;
	count = 0;   //还没有放置任何皇后
}

bool Queens::is_solved() const
{
	if(count == board_size)
		return true;
	else
		return false;
}

void Queens::print() const
{
	cout << "下面是解决" << board_size << "皇后问题的一组解(\"O\"表示该位置有皇后,\"X\"表示给位置无皇后):" << endl;
	int i,j;
	for(i = 0;i < board_size;i++)
	{
		for(j = 0;j < board_size;j++)
		{
			if(queen_square[i][j])
				cout << "O  " ;
			else
				cout << "X  " ;
		}
		cout << endl;
	}
}

bool Queens::unguarded(int col) const
{
	//先把当前的坐标表示出来
	int x = count;
	int y = col; 
	int i,j;
	for(i = 0;i < board_size;i++)
	{
		if(i != y && queen_square[x][i])
			return false;
	}
	for(j = 0;j < board_size;j++)
	{
		if(j != x && queen_square[j][y])
			return false;
	}
	for(i = 1;i < board_size;i++)
	{
		if(x - i >= 0 && x - i < board_size && y - i >= 0 && y - i < board_size)
		{
			if(queen_square[x-i][y-i])
				return false;
		}
		if(x + i >= 0 && x + i < board_size && y + i >= 0 && y + i < board_size)
		{
			if(queen_square[x+i][y+i])
				return false;
		}
		if(x + i >= 0 && x + i < board_size && y - i >= 0 && y - i < board_size)
		{
			if(queen_square[x+i][y-i])
				return false;
		}
		if(x - i >= 0 && x - i < board_size && y + i >= 0 && y + i < board_size)
		{
			if(queen_square[x-i][y+i])
				return false;
		}
	}
	return true;
}

void Queens::insert(int col)
{
	queen_square[count][col] = true;
	count++;
}

void Queens::remove(int col)
{
	count--;
	queen_square[count][col] = false;
}

void Queens::solve_from(Queens &configuration)
{
	if(configuration.is_solved())
		configuration.print();
	else
	{
		for(int col = 0;col < configuration.board_size;col++)
		{
			if(configuration.unguarded(col))
			{
				configuration.insert(col);   //在(count,col)处放置皇后
				solve_from(configuration);   //递归,继续求解
				configuration.remove(col);   //去掉先前在(count,col)处放置的皇后
			}
		}
	}
}

 

//test.cpp
#include <iostream>
#include "Queens.h"
//#include <vector>
using namespace std;

int main()
{
	int n = 8;   //尝试解决8皇后问题
	Queens qq(n);
	qq.solve_from(qq);
	return 0;
}

 

转载于:https://www.cnblogs.com/sysu-blackbear/p/3188241.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值