n皇后概率演算法與確定演算法折衷考慮最後解法
阿新 • • 發佈:2018-12-15
#include "pch.h" #include <iostream> #include <vector> #include <random> #include <ctime> #include <time.h> #include <set> #include <sys/timeb.h> using namespace std; #define NUMOFQUEEN 20//12~20 //uniform返回1到x的一個數 static int seeds; int uniform(int x) { uniform_int_distribution<int> u(1, x); default_random_engine e(seeds++); return u(e); } //回溯法求n皇后 bool backTrace2(int k, vector<int> tryV, set<int> &col, set<int> &diag45, set<int> &diag135, int &searchNode) { /*vector<int> tryV(1+NUMOFQUEEN); set<int> col, diag45,diag135;*/ //求k到NUMOFQUEEN皇后怎麼放置,包括第k和第NUMOFQUEEN個皇后. int j = 1; while (k <= NUMOFQUEEN) { bool findJ = false; for (; j <= NUMOFQUEEN; ++j) { if (col.find(j) == col.end() && diag45.find(j - k) == diag45.end() && diag135.find(j + k) == diag135.end()) { findJ = true; break; } } if (findJ) { ++searchNode; tryV[k] = j; col.insert(j); diag45.insert(j - k); diag135.insert(j + k); ++k; j = 1; } else { --k; j = tryV[k]; if (j == 0) return false; tryV[k] = 0; col.erase(col.find(j)); diag45.erase(diag45.find(j - k)); diag135.erase(diag135.find(j + k)); ++j; } } if (k == 1 + NUMOFQUEEN) { return true; } else return false; } //隨機演算法求n皇后 bool QueensLV2(int &searchNode, int stepVegas) { set<int> col, diag45, diag135;//分別是已用的列、45度方向的行列之差、135度方向的行列之和 vector<int> tryV(NUMOFQUEEN + 1);//(k,tryV[k})表示第k的皇后放置的位置 int k = 0;//行號 int j = 0;//列號 //毫秒級時間戳,用於生成隨機數 struct timeb tp; ftime(&tp); int seeds = tp.time / 1000 + tp.millitm;//隨機數初始種子 while (k < stepVegas) { int nb = 0;//nb表示當前行可以放置的位置數目 for (int i = 1; i <= NUMOFQUEEN; ++i) { if (col.find(i) == col.end() && diag45.find(i - k - 1) == diag45.end() && diag135.find(i + k + 1) == diag135.end()) { ++nb; if (uniform(nb) == 1)//從nb的位置中隨機返回一個 j = i; } } if (nb > 0) { k++; tryV[k] = j;//將列號記錄下來 col.insert(j); diag45.insert(j - k); diag135.insert(j + k); ++searchNode;//搜尋節點增加 } if (nb == 0) break; } if (k == stepVegas) { return(backTrace2(k + 1, tryV, col, diag45, diag135, searchNode)); } else return false; } int main() { struct timeb tp; ftime(&tp); seeds = tp.millitm + tp.time / 1000; cout << "n="<<NUMOFQUEEN<<"\nstepVegas s p t(ms)\n"; int stepVegas = 0; for (; stepVegas <= NUMOFQUEEN; ++stepVegas) { int sum = 0; int searchNode = 0; int j = 0; clock_t start, finish; double totaltime; start = clock();//開始時鐘 for (int i = 0; i < 10; ++i) { while (!QueensLV2(searchNode, stepVegas)) ++j; } finish = clock();//結束時鐘 totaltime = (double)(finish - start); sum += searchNode; cout << stepVegas << " " << sum / 10.0 << " " << 1.0 - j / (10.0 + j) << " " << totaltime << endl; } return 0; }