我写了两个程序:
但是我不知道要这么快!我想要更快地执行此操作的算法。
我想以更快的方式尽快解决1000个皇后的问题。
这是我的爬山代码:
// N queen - Reset Repair Hill Climbing.cpp // open-mind.ir #include "stdafx.h" #include <vector> #include <iostream> #include <fstream> #include <time.h> #include <iomanip> using namespace std; //print solution in console void printBoardinTerminal(int *board, int len) { for (int i = 0; i < len; i++) { for (int j = 0; j < len; j++) { if (j == board[i]) { cout << 1 << " "; } else { cout << 0 << " "; } } cout << endl; } } //print solution in File void printBoardinFile(int *board, int len) { ofstream fp("output.txt", ios::out); fp << "Answer for " << len << " queen: \n \n"; for (int i = 0; i < len; i++) { for (int j = 0; j < len; j++) { fp << "----"; } fp << "\n|"; for (int j = 0; j < len; j++) { if (j == board[i]) { fp << setw(4) << "* |" ; } else { fp << setw(4) << " |"; } } fp << "\n"; } } //The number of queens couples who are threatened themself int evaluate(int *board, int len) { int score = 0; for (int i = 0; i < len - 1; i++) { for (int j = i + 1; j < len; j++) { if (board[i] == board[j]) { score++; continue; } if (board[i] - board[j] == i - j) { score++; continue; } if (board[i] - board[j] == j - i) { score++; continue; } } } return score; } //generate new state from current state int* generateBoard(int *board,int len) { vector <int> choice; int temp; int score; int eval = evaluate(board, len); int k; int *boardOut; boardOut = new int [len]; for (int i = 0; i < len; i++) { boardOut[i] = board[i]; } for (int i = 0; i < len; i++) { choice.clear(); choice.push_back(boardOut[i]); temp = boardOut[i]; for (int j = 0; j < len; j++) { boardOut[i] = j; k = evaluate(boardOut, len); if (k == eval) { choice.push_back(j); } if (k < eval) { choice.clear(); choice.push_back(j); eval = k; } } boardOut[i] = choice[rand() % choice.size()]; } return boardOut; } //in this function , genarate new state by pervious function and if it has better value then replaces that by current state bool findNextState(int *board, int len) { int maineval = evaluate(board, len); int *tempBoard; tempBoard = generateBoard(board, len); if (evaluate(tempBoard, len) < maineval) { for (int p = 0; p < len; p++) { board[p] = tempBoard[p]; } return true; } return false; } // make random initial state , put one queen in each row void initialRandomBoard(int * board, int len) { bool access; int col; for (int i = 0; i < len; i++) { board[i] = rand() % len; } } //this function include a loop that call findNextState function , and do that until reach solution //if findNextState function return NULL then we reset current state void SolveNQueen(int len) { cout << "The program is under process! wait!" << endl; int *board; board = new int[len]; initialRandomBoard(board, len); while (evaluate(board, len) != 0) { if (!findNextState(board, len)) { initialRandomBoard(board, len); } } // cout << endl << "Anwser for " << len << " queens: "<< endl << endl; printBoardinTerminal(board, len); printBoardinFile(board, len); // } int main() { int n; srand(time(NULL)); cout << "Enter number \'N\', \'N\' indicate numbers of queens in \"N * N\" chess board: " << endl; cin >> n; if (n < 4) { cout << "\'n\' must be uper than 3!" << endl; exit(1); } SolveNQueen(n); cout << endl << "As well , you can see result in \"output.txt\"." << endl << endl; return 0; }
注意:此答案假设您有兴趣寻找 一种 有效的解决方案。如果您需要找到 所有 解决方案,这将无济于事。
Russell和Norvig撰写的《人工智能:一种现代方法》第二版在第143页的第5章:约束满足问题中有一张表,比较了各种任务的各种约束满足问题算法。(最新版本是第三版,看起来约束约束问题现在是第6章。)
根据他们的结果,在针对 n -Queens问题测试的算法中,最小冲突局部搜索启发式算法得分最高,平均要求4K检查,而回溯和前向检查则需要> 40,000K。
该算法非常简单:
for
在最后一步中,我假设每个女王/王后都被限制在她的栏中,因此她只能更改该栏中的行。如果有几行将当前皇后区的冲突最小化,则可以在其中任意选择。
而已。它是完全随机的,并且效果很好。
我在这里有一条笔记,内容是关于我不记得我实现该算法时得到的 n 值,并说我知道我获得了100以上的值。我没有找到我的旧代码,但我还是决定将某些东西放在一起。事实证明,这种方法比我记得的要有效得多。以下是10个皇后区的结果:
Starting Configuration: 14 0 2 13 12 17 10 14 14 2 9 8 11 10 6 16 0 7 10 8 Solution found Ending Configuration: 17 2 6 12 19 5 0 14 16 7 9 3 1 15 11 18 4 13 8 10 Elapsed time (sec): 0.00167 Number of moves: 227
在不尝试优化代码的情况下,以下是针对不同问题大小的大致计时:
Queens ~Time(sec) ====== ========== 100 0.03 200 0.12 500 1.42 1000 9.76 2000 72.32 5000 1062.39
我只为5000个皇后运行了最后一个,但是在不到18分钟的时间内找到解决方案的速度比我预期的要快。