8數碼問題的C 解決方案

2021-07-07 02:37:50 字數 1392 閱讀 5953

引子:我接觸8數碼問題是在研一的時候上的《人工智慧》課上,在某一章節介紹完深度優先搜尋、廣度優先搜尋、貪婪搜尋、a*搜尋四種經典搜尋策略以後,章節後面的一道習題便是讓學生程式設計求解8數碼問題。書上並未給出答案,我當時用不同的搜尋策略分別實現了程式求解,但是普遍效率不高。這兩天閒來無事,再把以前的程式翻出來看,決定重寫乙個。

程式介面:下圖是程式執行的介面,程式從使用者指定的狀態開始搜尋,直到找到目標狀態。

在8數碼問題中,只有空格(用數字0表示)可以移動,它每移動一步就是和相鄰的乙個數碼交換一次位置。

上圖左邊的控制台上顯示得的是(空格的)移動過程,經過20步以後達到目標狀態,如上圖右側所示。順便說下,鄙人的電腦是11年的thinkpad e520,2.2ghz的i3處理器,32位win7系統。

**細節:關於8數碼問題的乙個重要結論是

[1]:兩個不同的狀態序列的逆序數,若奇偶性一致,則二狀態可以互達,否則不能互達。示例:狀態序列230148675的逆序數(0不考慮)是1+1+3+1+1=7.

演算法c++源**和可執行程式

檔案均上傳到了。

程式提供3中搜尋模式

程式提供2種啟發式函式:第一種是計算有多少個不在正確位置上的數碼的個數來作為當前節點和目標節點的相似性度量;第二種是為每個錯誤放置的數碼,計算其到正確位置的城市距離,由這些距離之和作為相似性度量。上圖的示例程式就是採用第二種啟發式。為了計算效率,我將啟發式函式的選擇用巨集來定義,如果需要修改啟發函式,則需要修改乙個巨集變數,並重新編譯程式。

程式中保留了大多的靈活性:

需要說明的是:本文示例圖中的目標狀態在計算上是最快捷的,首先取數很方便,一般地檢視目標在第i個位置上的值,則需要訪問陣列goal[i],而這裡goal[i]==i,故而無需訪問陣列;第二,要想知道數碼n的目標位置,則需要找到goal[i]==n,然後row=i/3,col=i%3. 但是這裡的話,row=n/3,col=n%3. 當我們用8位無符號整型來表示各個數碼值(0~8)時,n/3和n%3操作是非常快的,比訪問陣列還快。

程式還提供一種玩遊戲模式,即使用者自己通過w,s,a,d四個鍵分別控制空格往上、下、左、右四個方向移動一步,功能很簡單,介面部分是用opencv做的。介面部分和搜尋部分是完全分離的,demo檔案中main函式部分顯示了如何將它們組合使用。

[1] 用mfc動態程式設計實現8數碼問題求解

越權問題的解決方案

一 橫向越權和縱向越權 越權定義 乙個正常的使用者a通常只能夠對自己的一些資訊進行增刪改查,但是由於程式設計師的一時疏忽未對資訊進行增刪改查的時候沒有進行乙個判斷,判斷所需要操作的資訊是否屬於對應的使用者,可以導致使用者a可以操作其他人的資訊。橫向越權定義 攻擊者嘗試訪問與他擁有相同許可權的使用者的...

utf 8亂碼解決方案

在解決亂碼問題前,必須先搞清楚幾個相關的問題。為每個jsp頁面設定了其編碼格式 utf 8 但傳遞資料到另一頁麵時依然顯示為亂碼?首先要需要了解的是web容器預設編碼是iso 8859 1,乙個漢字占用兩個位元組,而在utf 8中乙個漢字占用三個位元組。所以在資料傳遞過程中,必須手動設定容器編碼格式...

utf 8亂碼解決方案

在解決亂碼問題前,必須先搞清楚幾個相關的問題。為每個jsp頁面設定了其編碼格式 utf 8 但傳遞資料到另一頁麵時依然顯示為亂碼?首先要需要了解的是web容器預設編碼是iso 8859 1,乙個漢字占用兩個位元組,而在utf 8中乙個漢字占用三個位元組。所以在資料傳遞過程中,必須手動設定容器編碼格式...