八数码问题:在3×3的方格棋盘上,摆放着1到8这八个数码,有1个方格是空的,其初始状态如图1所示,要求对空格执行空格左移、空格右移、空格上移和空格下移这四个操作使得棋盘从初始状态到目标状态。
搜索顺序有两种:
(1)两个方向交替进行扩展
(2)每次选择节点少的那个扩展
一般来说方法(2)可以克服两端生长不平衡的现象
// eight.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include<vector> #include<algorithm> #include<iostream> using namespace std; #define N 3 #define SIZE 9 typedef unsigned char BYTE; /*const int src[N][N] = { { 2, 5, 4 }, { 3, 0, 7 }, { 1, 8, 6 } };*/ const int src[N][N] = { { 8, 7, 1 }, { 5, 2, 6 }, { 3, 4, 0 } }; /*const int dst[N][N] = { { 1, 2, 3 }, { 8, 0, 4 }, { 7, 6, 5 } };*/ const int dst[N][N] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 0 } }; struct Code { BYTE value[SIZE]; bool operator== (const Code &a) const { for (int i = 0; i < SIZE;i++) if( a.value[i] !=value[i]) return false; return true; } Code& operator=(const Code& a) { for (int i = 0; i < SIZE; i++) value[i] = a.value[i]; return *this; } }; Code up(Code a) { int ii=-1; for (int i = 0; i < SIZE; i++) if (a.value[i] == 0) { ii = i; break; } if (ii > 2) { BYTE temp = a.value[ii - 3]; a.value[ii - 3] = 0; a.value[ii] = temp; } return a; } Code right(Code a) { int ii = -1; for (int i = 0; i < SIZE; i++) if (a.value[i] == 0) { ii = i; break; } if (ii>=0&&(ii+1)%3!=0) { BYTE temp = a.value[ii +1]; a.value[ii +1] = 0; a.value[ii] = temp; } return a; } Code down(Code a) { int ii = -1; for (int i = 0; i < SIZE; i++) if (a.value[i] == 0) { ii = i; break; } if (ii>=0&&ii <6) { BYTE temp = a.value[ii + 3]; a.value[ii + 3] = 0; a.value[ii] = temp; } return a; } Code left(Code a) { int ii = -1; for (int i = 0; i < SIZE; i++) if (a.value[i] == 0) { ii = i; break; } if (ii >= 0&&ii%3!=0) { BYTE temp = a.value[ii - 1]; a.value[ii - 1] = 0; a.value[ii] = temp; } return a; } vector<Code>solution; bool expand(vector<vector<Code>>&tobeexpanded, vector<vector<Code>>&a_b, vector<Code>&front_tobeexpanded, vector<Code>&front_a_b) { vector<vector<Code>>bbb; vector<Code>::iterator it; front_tobeexpanded.clear(); for (int i = 0; i < tobeexpanded.size(); i++) { if (!(up(tobeexpanded[i].back()) == tobeexpanded[i].back()) && find(tobeexpanded[i].begin(), tobeexpanded[i].end(), up(tobeexpanded[i].back())) == tobeexpanded[i].end()) { it = find(front_a_b.begin(), front_a_b.end(), up(tobeexpanded[i].back())); if (it != front_a_b.end()) { solution = a_b[it - front_a_b.begin()]; reverse(tobeexpanded[i].begin(), tobeexpanded[i].end()); solution.insert(solution.end(), tobeexpanded[i].begin(), tobeexpanded[i].end()); return true; } front_tobeexpanded.push_back(up(tobeexpanded[i].back())); bbb.push_back(tobeexpanded[i]); bbb.back().push_back(up(tobeexpanded[i].back())); } if (!(right(tobeexpanded[i].back()) == tobeexpanded[i].back()) && find(tobeexpanded[i].begin(), tobeexpanded[i].end(), right(tobeexpanded[i].back())) == tobeexpanded[i].end()) { it = find(front_a_b.begin(), front_a_b.end(), right(tobeexpanded[i].back())); if (it != front_a_b.end()) { solution = a_b[it - front_a_b.begin()]; reverse(tobeexpanded[i].begin(), tobeexpanded[i].end()); solution.insert(solution.end(), tobeexpanded[i].begin(), tobeexpanded[i].end()); return true; } front_tobeexpanded.push_back(right(tobeexpanded[i].back())); bbb.push_back(tobeexpanded[i]); bbb.back().push_back(right(tobeexpanded[i].back())); } if (!(down(tobeexpanded[i].back()) == tobeexpanded[i].back()) && find(tobeexpanded[i].begin(), tobeexpanded[i].end(), down(tobeexpanded[i].back())) == tobeexpanded[i].end()) { it = find(front_a_b.begin(), front_a_b.end(), down(tobeexpanded[i].back())); if (it != front_a_b.end()) { solution = a_b[it - front_a_b.begin()]; reverse(tobeexpanded[i].begin(), tobeexpanded[i].end()); solution.insert(solution.end(), tobeexpanded[i].begin(), tobeexpanded[i].end()); return true; } front_tobeexpanded.push_back(down(tobeexpanded[i].back())); bbb.push_back(tobeexpanded[i]); bbb.back().push_back(down(tobeexpanded[i].back())); } if (!(left(tobeexpanded[i].back()) == tobeexpanded[i].back()) && find(tobeexpanded[i].begin(), tobeexpanded[i].end(), left(tobeexpanded[i].back())) == tobeexpanded[i].end()) { it = find(front_a_b.begin(), front_a_b.end(), left(tobeexpanded[i].back())); if (it != front_a_b.end()) { solution = a_b[it - front_a_b.begin()]; reverse(tobeexpanded[i].begin(), tobeexpanded[i].end()); solution.insert(solution.end(), tobeexpanded[i].begin(), tobeexpanded[i].end()); return true; } front_tobeexpanded.push_back(left(tobeexpanded[i].back())); bbb.push_back(tobeexpanded[i]); bbb.back().push_back(left(tobeexpanded[i].back())); } } tobeexpanded = bbb; return false; } void DBFS() { vector<vector<Code>>aa,bb; Code start, ending; for (int i = 0; i < SIZE; i++) { start.value[i] = src[i / 3][i % 3]; ending.value[i] = dst[i / 3][i % 3]; } vector<Code>a1, b1; a1.push_back(start); b1.push_back(ending); aa.push_back(a1); bb.push_back(b1); vector<Code>front_a, front_b; front_a.push_back(start); front_b.push_back(ending); while (true) { if (aa.size()>bb.size()) { if(expand(bb, aa, front_b, front_a)) return; } else { if(expand(aa, bb, front_a, front_b)) return; } } } int _tmain(int argc, _TCHAR* argv[]) { DBFS(); system("pause"); return 0; }