您的位置:首页 > 其它

n王后问题(分支限界)

2015-12-17 09:50 302 查看
#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: