基於A星演算法的8數碼問題求解方案設計

2022-05-25 10:54:04 字數 2958 閱讀 8883

基於a星演算法解決8數碼問題

的程式設計實現

姓名:學號:

2010-11-25

一、問題描述

8數碼問題又稱9宮問題,與遊戲「華容道」類似。意在給定的棋格的8個格仔內分別放乙個符號,符號之間互不相同,餘下的一格為空格。並且通常把8個符號在棋格上的排列順序稱作8數碼的狀態。

開始時,規則給定乙個初始狀態和乙個目標狀態,並要求被試者對棋格內的符號經過若干次移動由初始狀態達到目標狀態,這個過程中只有空格附近的符號可以朝空格的方向移動,且每次只能移動乙個符號。

為方便程式設計和表示,本文中8個格仔內的符號分別取1—8的8個數字表示,空格用0表示。並給定8數碼的初始狀態和目標狀態分別如圖1、2所示。

圖1 初始狀態圖2 目標狀態

則要求以圖1為初始狀態,通過交換0和0的上、下、左、右四個方位的數字(每次只能和其中乙個交換),達到圖2所示目標狀態。

二、演算法設計

根據任務要求,本文採用a*搜尋演算法。但要在計算機上通過程式設計解決該問題,還應當解決該問題在計算機上表示的方式,並設計合適的啟發函式,以提高搜尋效率。

①狀態的表示

在a*演算法中,需要用到open表和closed表,特別是在open表中,待擴充套件節點間有很嚴格的擴充套件順序。因此在表示當前狀態的變數中,必須要有能指向下乙個擴充套件節點的指標,以完成對open表中元素的索引。從這一點上看,open表中的元素相互間即構成了乙個線性表,因此初步選定使用結構體表示問題的狀態。

如圖3所示,表示問題的結構體包括表示當前節點狀態的data和指向open表中下乙個待擴充套件節點的指標next。

圖3 結構體

現在進一步考慮data中包括的內容:

如圖1、2所示,8數碼問題的提出是以乙個數表表示的,因此本文中採用乙個的二維陣列s[3][3]表示當前狀態的具體資訊。而為了保證在搜尋到目標狀態後能夠順利復現尋優路徑,當前狀態的data中還應該包括乙個指向其父節點的指標father,這樣,才能在達到目標狀態後,通過指標father逐層回溯到初始狀態,即復現尋優路徑。

另一方面,a*搜尋演算法是通過考察節點的代價值來決定open表的排序的,因此在表示當前狀態的data中還應該有對當前節點代價值的描述。

根據a*演算法的定義,當前節點的代價值由估價函式給出,即:

其中:表示當前節點n在搜尋樹中的深度;

是啟發函式。

因此,在data還應包括表示當前節點代價、深度和啟發資訊的、、。

最後,為提高程式的執行效率,減少程式擴充套件節點時搜尋量,將當前0所處位置(i_0:0在s[3][3]中所處行號,j_0:0在s[3][3]中所處列號)也儲存在data中。

綜上所述,問題狀態的表示如下圖所示。

圖4 問題的狀態表示

②啟發函式的設計

根據a*演算法的定義,啟發函式應滿足:。

其中:表示從當前節點n到目標節點s_g的最優路徑的實際代價。

並且,在滿足的條件下,的值越大它所攜帶的啟發性資訊越多,a*演算法搜尋時擴充套件的節點就越少,搜尋效率就越高。

在8數碼問題中,常用的啟發函式為: 「不在位」數碼個數,或數碼「不在位」的距離和。顯然,後者的不小於前者,因此本文中採用數碼「不在位」的距離和作為啟發函式。

③規則庫設計

0在某一位置時,能選擇向左、向右、向上、向下移動中的哪幾種策略進行移動,主要是由當前0所處位置(更具體地說是當前位置的行列號)和其祖父節點(為提高搜尋效率,新擴充套件的節點應當至少不為其祖父節點)所決定的。

當然,按照a*演算法的思想,每擴充套件出乙個新節點,都要判斷其是否為有效子節點,不為有效子節點的不能加入到open表中。這一段的具體過程可以參考程式流程部分。

因此移動的規則庫可以寫成如下形式:

左移:if(p->j_0>=1) //空格所在列號不小於1,可左移

{temp=p->father;

if(temp!=null&&temp->i_0==p->i_0&&temp->j_0-1==p->j_0新節點與其祖父節點相同,無操作

else //新節點與其祖父節點不同,或其父節點為起始節點

擴充套件新節點,並判斷是否加入open表)//詳細**見源程式

end左移

右移:if(p->j_0<=1) //空格所在列號不大於1,可右移

{temp=p->father;

if(temp!=null&&temp->i_0==p->i_0&&temp->j_0+1==p->j_0新節點與其祖父節點相同,無操作

else //新節點與其祖父節點不同,或其父節點為起始節點

擴充套件新節點,並判斷是否加入open表)//詳細**見源程式

end右移

上移:if(p->i_0>=1) //空格所在列號不小於1,可上移

{temp=p->father;

if(temp!=null&&temp->i_0==p->i_0-1&&temp->j_0==p->j_0新節點與其祖父節點相同,無操作

else //新節點與其祖父節點不同,或其父節點為起始節點

擴充套件新節點,並判斷是否加入open表)//詳細**見源程式

end上移

下移:if(p->i_0<=1) //空格所在列號不大於1,可下移

{temp=p->father;

if(temp!=null&&temp->i_0==p->i_0+1&&temp->j_0==p->j_0新節點與其祖父節點相同,無操作

else //新節點與其祖父節點不同,或其父節點為起始節點

擴充套件新節點,並判斷是否加入open表)//詳細**見源程式

end下移

④程式流程

主程式流程圖:

其中,擴充套件節點n的具體步驟如下:

a) 首先判斷其是否在closed表已經出現過, 如果出現過,並且新節點的代價值比其小,則應將其從closed表刪除,同時將新節點加入到open表;如果沒有出現過,則轉b。

b) 判斷其是否已經存在於open表中待擴充套件,如果出現過,並且新節點的代價值比其小,則應將其從open表刪除,同時將新節點加入到open表;如果沒有出現過,則說明該節點為乙個全新的節點,轉c。

c) 將該節點加入open表。

三、執行結果

基於GraphicEX的數碼影像瀏覽管理系統

基於graphicex的數碼影像瀏覽管理系統作者 惠燕潘煜 中小企業管理與科技 上旬刊 2013年第12期摘要 隨著計算機技術的發展和具有照相功能的手機的普及,的使用已經深入人們的生活之中。為了方便人們管理使用這些 本文介紹了如何開發滿足普通使用者的需求,介面美觀 整潔,功能易學易用的數碼影像瀏覽管...

基於圖形計算器的演算法實現與演算法初步教學

作者 楊一奮 數學教學通訊 初等教育 2014年第12期 摘 要 作為一種實現演算法的有力工具,圖形計算器不但可以將演算法化的思路落到實處,更可以在視覺化的基礎上提供分析演算法的通道.文章從例項出發,詳解了演算法實現和演算法分析的具體操作,並提出基於圖形計算器的手持特點,可以使 演算法 成為學生主動...

基於模擬退火演算法的PID引數優化

pid 控制結構簡單,可靠性強,容易實現,對模型誤差具有魯棒性以及可靠性高等優點,是現代工業中最常用的控制方法,被廣泛用於冶金 化工 電力 輕工和機械等工業過程控制中 1 pid 的控制效果與其引數比例 積分和微分有著直接關係,因此如何進行pid 控制引數優化,從而獲得最優引數,是大家關注的乙個重要...