八数码问题——双向广度优先搜索解决
八數碼問題:在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; }題目來源:NOIP2002提高組試題
描寫敘述 Description
已知有兩個字串 A$, B$ 及一組字串變換的規則(至多6個規則):
A1$ -> B1$
A2$ -> B2$
規則的含義為:在 A$中的子串 A1$ 能夠變換為 B1$、A2$ 能夠變換為 B2$ …。
比如:A$='abcd' B$='xyz'
變換規則為:
‘abc’->‘xu’ ‘ud’->‘y’ ‘y’->‘yz’
則此時。A$ 能夠經過一系列的變換變為 B$,其變換的過程為:
‘abcd’->‘xud’->‘xy’->‘xyz’
共進行了三次變換,使得 A$ 變換為B$。
輸入格式 Input Format
A$ B$
A1$ B1$ \
A2$ B2$ |-> 變換規則
... ... /
全部字符串長度的上限為 20。
輸出格式 Output Format
若在 10 步(包括 10步)以內能將 A$ 變換為 B$ 。則輸出最少的變換步數;
否則輸出"NO ANSWER!"
例子輸入:
abcd xyz
abc xu
ud y
y yz
例子輸出:
3
題目類型:雙向廣搜
總結
以上是生活随笔為你收集整理的八数码问题——双向广度优先搜索解决的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 保护企业网络安全,不要忽视数据
- 下一篇: ArcGIS License Manag