n王后问题(分支限界)

#include <iostream>
#include <queue>
using namespace std;

class QNode{
public:
	int *x;//记录当前的数值
	int i;//记录自己是第几层,即已经放了多少个
};

class Queen{
	friend int main();
public:
	int* bestx;//记录最好
	int n;//有几个王后
	Queen(int n);//初始化
	void output();//输出结果
	void NewNode(QNode *&N, QNode *&E, int i);//增加新的节点
	void Complete(QNode *&E);//完成
	bool Check(QNode *E);//检查是否可以入队(剪支函数)
	bool getNext(queue<QNode*> &q, QNode *&E);//获取下一个节点
};

Queen::Queen(int n){
	queue<QNode*> q;//分支限界的队列
	bestx = new int[n + 1];
	this->n = n;
	QNode *E;//记录当前活节点
	QNode *N;//记录新生的孩子节点
	E = new QNode;
	E->i = 0;
	E->x = new int[n + 1];
	for (int j = 1; j <= n; j++){//初始化根节点,防止在同一列上,减少循环和判断次数
		E->x[j] = j;
	}
	while (1){
		if (E->i == n){//到达最后一层找到解
			Complete(E);
			break;
		}
		else{
			for (int i = E->i + 1; i <= n; i++){
				NewNode(N, E, i);
				if (Check(N)){
					q.push(N);
				}
			}
		}
		if (!getNext(q, E)){//队列为空结束
			break;
		}
	}
	output();
}

void Queen::Complete(QNode *&E){
	for (int j = 1; j <= n; j++){
		bestx[j] = E->x[j];
	}
}

bool Queen::Check(QNode *E){
	for (int j = 1; j < E->i; j++){
		if ((abs(E->i - j) == abs(E->x[E->i] - E->x[j]) || (E->x[j] == E->x[E->i])))//前面的是检查是否在同一对角线上后面是是否在同一列上
			return false;
	}
	return true;
}

void Queen::NewNode(QNode *&N, QNode *&E, int i){
	N = new QNode;
	N->i = E->i + 1;
	N->x = new int[n + 1];
	for (int j = 1; j <= n; j++){//复制父节点的信息
		N->x[j] = E->x[j];
	}
	N->x[N->i] = E->x[i];//将父节点剩下的选择一个一个换上去然后判断
	N->x[i] = E->x[N->i];
}

bool Queen::getNext(queue<QNode *> &q, QNode *&E){
	if (q.empty()){
		cout << "没有找到解!" << endl;
		return false;
	}
	else{
		E = q.front();
		q.pop();
		return true;
	}
}

void Queen::output(){
	for (int i = 1; i <= n; i++){
		cout << bestx[i] << " ";
	}
	cout << endl;
}

int main(){
	int n = 0;
	cout << "请输入一个n:" << endl;
	cin >> n;
	Queen Demo(n);
	return 0;
}

    原文作者:分支限界法
    原文地址: https://blog.csdn.net/horizon_zore/article/details/50337655
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞