不介意用C++再写一遍(一)
八数码问题研究有一段时间了,但总感觉速度太慢,验证起来不爽,所以把多年前学的C++再温习了一遍。先写一个简单的(单向宽搜)看看成效。
#include<iostream>
#include<set>
#include<time.h>
using namespace std;
set<string> sun;
set<string> sum;
set<string> summ;
//'0'从某个位置移到到另外一个位置的所有集合。例如'0'在位置0时,可以移到到位置1和位置3(即向右移到和向下移动)。
int base[9][4] = { {1, 3},{0, 2, 4},{1, 5},{0, 4, 6},{1, 3, 5, 7},{2, 4, 8},{3, 7},{4, 6, 8},{5, 7} };
//与上对应,'0'在某个位置的集合元素个数。
int base_num[9] = { 2, 3, 2, 3, 4, 3, 2, 3, 2 };
string source = "723164805";//723164805//723164805//876504321//807236514//187305462//706382514//
string target = "813504672";//123804765//813504672//123405678//123405678//123456780//123405678//
//由一个状态生成多个次生状态
set<string> moving(string state) {
set<string> s;
int zero_index=0;
for (int i = 0; i < 9; i++)
if (state[i] == '0')zero_index = i;
int count = base_num[zero_index];
for (int j : base[zero_index]) {
string temp = "";
for (int i = 0; i < 9; i++) temp += state[i];
swap(temp[j], temp[zero_index]);
s.insert(temp);
if (!--count)break;
}
return s;
}
int main() {
time_t start_time = clock();
int cc = 0;
summ.insert(source);
while (true) {
cc++;
sum.clear();
for (auto ss : summ) {
sun = moving(ss);
for (auto s : sun) {
if (s == target) {
cout << "成功,共搜索" << cc << "层!" << endl;
cout << "耗时" << (double)(clock() - start_time) / CLOCKS_PER_SEC <<"s"<< endl;
exit(0);
}
sum.insert(s);
}
}
summ = sum;
}
system("pause");
return 0;
}
成功,共搜索19层!
耗时4.639s