A 演算法解決八數碼問題(C 版本)

2021-07-10 09:16:38 字數 3706 閱讀 1570

八數碼問題也稱為九宮問題。在3×3的棋盤,擺有八個棋子,每個棋子上標有1至8的某一數字,不同棋子上標的數字不相同。棋盤上還有乙個空格,與空格相鄰的棋子可以移到空格中。要求解決的問題是:給出乙個初始狀態和乙個目標狀態,找出一種從初始轉變成目標狀態的移動棋子步數最少的移動步驟。

關鍵之處:

要維護兩個結構:

每次從open表中選擇f值(f = g + h)最小的點進行拓展,對於拓展出的新節點要,如果已經訪問過且此時f值比以前訪問時更優時,要更新close表,並將此節點重新插入到open表中。

#include 

#include

#include

#include

#include

//#include "process.cpp";

#define size 3//棋盤的大小 size*size

using

namespace

std;

/** *定義方案節點

*/typedef

struct node

pnode;

int x_axis = ;

int y_axis = ;

/** *輸出方案

*/void print(vector

board, int rc)

cout

/cout<

}/**

*將遍歷到的當前節點輸出到文字檔案中

*/void out_data(pnode &node)

outdata

*判斷棋盤是否有序

* *@param vectorboard

*@return bool是否有序

*/bool is_ordered(vector

board)

} return

true;

}/**

*定義heuristic函式 探索函式

* *@param vectorboard , int rc 表示解決方案是rc*rc的 r&c

*@return int value of heuristic

*/int heuristics(vector

board,int rc)

return distance;

}/**

*same_plan()判斷兩個vector是否相等

*即判斷兩個方案是否相等

* *@param vectorboard1, vectorboard2

*@return bool

*/bool same_plan(vector

board1, vector

board2)

//判斷每乙個元素是否對應相等

for(int i = 0; i < board1.size(); ++i)

}//所有元素都比較完畢以後

return

true;

}/**

*in_open()函式,判斷乙個節點是否在open表中

* *@param pnode, listopen

*@return bool true--在ope表中, false--不再open表中

*/bool in_open(pnode plan, list

&open)

} return

false;

}/**

*in_close()函式,判斷乙個節點是否在close表中

* *@param pnode, vectorclose

*@return bool true 在close表中 false不再表中

*/bool in_close(pnode plan, vector

&close)

} //都遍歷完畢以後依然沒有找到

return

false;

} /**

*insert_close()函式 將正在訪問的節點新增到close表中

* *@param pnode, vectorint insert_close(pnode plan, vector

& close)

/** *insert_open()函式 將新生成的plan新增到fringe上去

* *@param pnode plan, listfringe

*@return fringe

*/bool insert_open(pnode plan, list

& open)

} //當走到這時,說明這個plan的fvalue是最大的

open.push_back(plan);

return

true;

}/**

*generate函式:生成新的解決方案

* *@param vectorboard, listl, int rc邊的長度;

*/void generate(list

& open, vector

&close)

} //想四個方向拓展,首先得判斷能否拓展

for(int i = 0; i < 4; i++)

else

}//找該節點應該插入的位置

bool inserted = false;

if(!inserted && (new_plan.h+new_plan.g) < ((*it).h+(*it).g))}}

else

if(in_close(new_plan, close))}}

else

}} return ;

}/**

*void get_path()函式,根據當前符合目標狀態的節點在close表中回溯,

* 從而獲得從起點到達目標終點的路徑

* *@param pnode, vectorclose

*@return null

*/void get_path(pnode plan, vector

&close, int plen)

//輸出當前節點

print(plan.board, plan.rc);

return get_path(close[plan.parent], close, ++plen);

}int main(int argc, char *argv)

} plan.rc = 3;

plan.g = 1;

plan.parent = -1; //標識起點

plan.h = heuristics(plan.board, plan.rc);

//生成open表,並將起點新增到表中

list

open;

open.push_back(plan);

//生成close表

vector

close;

while(!open.empty())

//產生新的方案

generate(open, close);

} //cout

0;}

[1 6 4 8 7 0 3 2 5]的輸入可以得到21步的最優解。

A A 演算法解決八數碼問題(C 實現)

1.狀態圖搜尋 1.1搜尋樹 搜尋過程中經過的節點和邊按原圖的連線關係構成乙個樹型的有向圖,稱為搜尋樹。1.2搜尋方式 樹式搜尋 記錄搜尋過程中所經過的所有節點和邊 1.3路徑的獲得 樹式搜尋 反向求解 2.搜尋演算法 2.1 closed表和open表 closed表對樹式搜尋來說儲存的是正在成長...

C STL解決八數碼問題

先放原始碼 大部分借鑑了書本的 隨後對部分 進行解釋 include include include define len 362880 using namespace std 八數碼問題 struct node int dir 4 2 int vis len long int factory in...

A 演算法解決八數碼問題(C 類改進版)

八數碼問題 在乙個3 3的棋盤中,分別用1,2,3,8表示八個數碼方格,用0表示空缺的方格,現給出乙個初始狀態和目標狀態,尋找出在評估函式f n g n h n 的限制下,以最少的步數到達目標狀態 一次將乙個數碼方格移動到空缺的方格中 其中,g n 表示n節點與目標狀態的 距離 h n 表示n節點與...