第1次实验——NPC问题(回溯算法、聚类分析)

来源:互联网 发布:华为云计算调研报告 编辑:程序博客网 时间:2024/06/10 06:22

1.八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种方法可以解决此问题。

       下面我将编程解决这个问题。

       我首先把此问题的求解延伸到N皇后问题,考虑到可能输出的结果会很多,我设定如果结果数大于或等于N种则只输出N种结果,如果结果数小于N种则输出全部结果,结果输出至文件output.txt中,单个结果为N*N的二维矩阵,其中Q代表皇后,X代表空。

 

下面是代码:

QueensQuestion.h

#pragma once#include <string>class QueensQuestion{public:QueensQuestion(int numOfQueen);~QueensQuestion(void);void answer();private:bool answer(int row);int output();int output(std::string &str);private:const int num;const char queen ;const char empty ;char **chessboard;std::string outputStr;};

 

QueensQuestion.cpp

#include "QueensQuestion.h"#include <iostream>#include <fstream>using namespace std;QueensQuestion::QueensQuestion(const int numOfQueen):num(numOfQueen),queen('Q'),empty('X'){chessboard = new char*[num];for (int i = 0; i != num ;++i){chessboard[i] = new char[num];}}QueensQuestion::~QueensQuestion(void){for (int i = 0; i != num ;++i){delete [] chessboard[i];}delete [] chessboard;}int QueensQuestion::output(){ofstream outFile("output.txt");if (!outFile){cout<<"写入文件output.txt失败!"<<endl;return -1;}if(outputStr.empty()){cout<<"没有合适的方案!"<<endl;return -2;}outFile<<outputStr<<endl;outFile.close();return 0;}int QueensQuestion::output(string &str){for (int i = 0; i != num ; ++i){for (int j = 0; j != num ; ++j){str += chessboard[i][j];}str += "\n";}str += "\n";return 0;}bool QueensQuestion::answer(int row)//第row行{for (int i=0 ; i!=num ; ++i)//第row行的第i个方格{bool judge = true;//判断是否不符合放棋要求,符合为true, 否则为falsefor (int j = 1 ; (row-j) != -1 ; ++j)//前第j行{if( chessboard[row-j][i] == queen ){judge = false;break;}if( chessboard[row-j][i-j] == queen ){judge = false;break;}if( chessboard[row-j][i+j] == queen ){judge = false;break;}}if (judge)//如果chessboard [row][i]符合放棋要求{chessboard[row][i] = queen;if ( row+1 == num )//最后一行{return true;}if ( answer(row+1) )//查找下一行{return true;}chessboard[row][i] = empty;//下一行不符合要求,清空当前方格,继续循环}}return false;}void QueensQuestion::answer(){for (int i=0 ; i!=num; ++i)//以第一行为基准{for (int j=0; j!=num ; ++j)//初始化矩阵{for (int k=0; k!=num ; ++k){chessboard[j][k] = empty;}}chessboard[0][i] = queen;//放置第一行的Queenif (answer(1)){output(outputStr);}}if (0 == output())cout<<"成功!计算结果详见output.txt"<<endl;}

上面就是解决N皇后问题的类定义与实现。

以下是测试代码:

main.cpp

#include <iostream>#include "QueensQuestion.h"int main (){int i = 0;std::cout<<"请输入皇后的数目:";std::cin>>i;QueensQuestion *eQQ =new QueensQuestion(i);eQQ->answer();delete eQQ;return 0;}

 

程序运行结果:

output.txt内容如下:

QXXXXXXXXXXXQXXXXXXXXXXQXXXXXQXXXXQXXXXXXXXXXXQXXQXXXXXXXXXQXXXXXQXXXXXXXXXQXXXXXXXXXQXXXXXXXXXQXXQXXXXXQXXXXXXXXXXXXXQXXXXXQXXXXXQXXXXXQXXXXXXXXXXXXXQXXXXXQXXXXXXXXXXQXQXXXXXXXXXQXXXXXXXXXQXXXXXQXXXXQXXXXXXXXXXXQXXXXXXXXXXQXQXXXXXXXXXXXXQXXXQXXXXXXXXXXQXXXXXXQXXXQXXXXXXXXXXQXXXXXXXXXQXXXXXXXXXQXQXXXXXXXXXXXXQXXXQXXXXXXXXXXQXXQXXXXXXXXXXXQXXXXQXXXXXXXXXXXXXQXXQXXXXXXXXXXXQXXXXQXXXXXXXXXXQXQXXXXXXXXXQXXXXXXXXXXXXQXXXXXQXXXXXQXXXXXQXXXXXXXXXXQXXXXXXXXXXQXQXXXXXXXXXQXXXXQXXXXXXXXXXXXXQXXXXXQXXXXXQXXXXXXXXXXQXX


 

0 0
原创粉丝点击