1. 程式人生 > >狀態空間搜尋——八數碼問題 Ja…

狀態空間搜尋——八數碼問題 Ja…

實驗一 狀態空間搜尋——八數碼問題

實驗報告

【注】原始碼將以附件的形式上傳,其中EightPuzzle.javavo類,EightPuzzleOperator.javautil類,EightPuzzleAlgorithm.java為演算法實現類。Main函式在EightPuzzleAlgorithm.java類中。

原始碼下載】百度網盤

一、實習目的和意義

理解和掌握狀態空間搜尋的策略。

二、實習內容

在一個3*3的九宮中有1~8個數及一個空格隨機地擺放在其中的個子裡,現在要求實現這個問題;將該九宮格調整為某種有序的形式。調整的規則是,每次只能將空格左上右下移動,試程式設計實現這一問題的求解。

三、實習要求

用你們學過的某種語言編寫程式,利用不同的搜尋策略進行狀態空間搜尋(如寬度優先搜尋、深度優先搜尋、有界深度優先搜尋、啟發式搜尋等)。

四、實驗總結

【實驗測試結果】

測試中的一組資料:

請輸入初始位置(其中輸入0代表空白塊,例如:2 8 3 1 0 4 7 6 5):

2 8 3 1 0 4 7 6 5

請輸入目標位置(其中輸入0代表空白塊,例如:2 8 3 1 4 0 7 6 5):

2 8 3 1 4 0 7 6 5

深度優先搜尋:

深度優先搜尋方法路徑!

2 8 3 1 0 4 7 6 5

2 8 3 0 1 4 7 6 5

2 8 3 7 1 4 0 6 5

2 8 3 7 1 4 6 0 5

2 8 3 7 1 4 6 5 0

2 8 3 7 1 0 6 5 4

2 8 3 7 0 1 6 5 4

2 8 3 0 7 1 6 5 4

2 8 3 6 7 1 0 5 4

2 8 3 6 7 1 5 0 4

2 8 3 6 7 1 5 4 0

2 8 3 6 7 0 5 4 1

2 8 3 6 0 7 5 4 1

2 8 3 0 6 7 5 4 1

2 8 3 5 6 7 0 4 1

2 8 3 5 6 7 4 0 1

2 8 3 5 6 7 4 1 0

2 8 3 5 6 0 4 1 7

2 8 3 5 0 6 4 1 7

2 8 3 0 5 6 4 1 7

2 8 3 4 5 6 0 1 7

2 8 3 4 5 6 1 0 7

2 8 3 4 5 6 1 7 0

2 8 3 4 5 0 1 7 6

2 8 3 4 0 5 1 7 6

2 8 3 0 4 5 1 7 6

2 8 3 1 4 5 0 7 6

2 8 3 1 4 5 7 0 6

2 8 3 1 4 5 7 6 0

2 8 3 1 4 0 7 6 5

終於找到了,b

有界深度優先搜尋:

有界深度優先搜尋方法路徑!

2 8 3 1 0 5 7 4 6

0 8 3 2 4 5 1 7 6

2 8 3 4 7 5 1 0 6

2 0 3 4 8 5 1 7 6

2 8 0 4 5 3 1 7 6

2 8 3 4 0 6 1 5 7

0 8 3 2 5 6 4 1 7

2 8 3 5 1 6 4 0 7

2 0 3 5 8 6 4 1 7

2 8 0 5 6 3 4 1 7

2 8 3 5 0 7 4 6 1

0 8 3 2 6 7 5 4 1

2 8 3 6 4 7 5 0 1

2 0 3 6 8 7 5 4 1

2 8 0 6 7 3 5 4 1

2 8 3 6 0 1 5 7 4

0 8 3 2 7 1 6 5 4

2 8 3 7 5 1 6 0 4

2 0 3 7 8 1 6 5 4

2 8 0 7 1 3 6 5 4

2 8 3 7 0 4 6 1 5

0 8 3 2 1 4 7 6 5

2 8 3 0 1 4 7 6 5

2 8 3 7 1 4 0 6 5

2 8 3 1 0 4 7 6 5

0 8 3 2 1 4 7 6 5

8 0 3 2 1 4 7 6 5

0 8 3 2 1 4 7 6 5

8 1 3 2 0 4 7 6 5

8 3 0 2 1 4 7 6 5

2 8 3 1 6 4 7 0 5

2 8 3 1 6 4 0 7 5

2 8 3 1 6 4 7 0 5

2 8 3 1 6 4 0 7 5

2 8 3 1 6 4 7 5 0

2 8 3 0 6 4 1 7 5

2 8 3 1 6 4 0 7 5

2 8 3 6 0 4 1 7 5

0 8 3 2 6 4 1 7 5

2 8 3 1 6 4 7 5 0

2 8 3 1 6 4 7 0 5

2 8 3 1 6 4 0 7 5

2 8 3 1 6 0 7 5 4

2 8 3 1 0 6 7 5 4

2 8 0 1 6 3 7 5 4

2 8 3 1 0 4 7 6 5

2 8 3 1 6 4 7 0 5

2 8 3 1 6 4 0 7 5

2 8 3 1 4 0 7 6 5

終於找到了,b

廣度優先搜尋:

廣度優先搜尋方法路徑!

2 8 3 1 0 4 7 6 5

2 0 3 1 8 4 7 6 5

2 8 3 1 4 0 7 6 5

終於找到了,b

由於上面的執行結果截圖不能一次截圖完畢,所以將其中的執行過程複製了下來,上面的程式碼均為Java原始碼。下面分別對上面的三種演算法使用自然語言描述。

【實驗演算法描述】

八數碼問題,是對給定的一個初始位置,然後經過多次移動找到目標位置,並列舉出其中的移動過程,最後可以找到既是可以成功,否則以失敗告終。是一種過程中無人為參與的一中求解方法。

深度優先搜尋:

深度優先搜尋演算法是按照一條路徑一直往下深度延伸其子節點的演算法,直到找到答案為止。也可能一直到達一個很深的深度之後還是沒有找到問題的答案,這樣就有可能出現棧溢位或者記憶體超界的情況(本實驗中數字組合相對較少,不會造成記憶體超限的情況)。在深度優先搜尋的求解過程中使用棧來儲存還未搜尋的節點,已經搜尋過的節點使用一個連結串列來儲存(避免重複的搜尋,屬於優化過程)。如果已經在連結串列中那麼就不在放到棧中,因為之前已經搜尋過了,不需要重複搜尋。當然在深度優先搜尋的過程中,不需要記錄其深度,因為不會用深度來限制搜尋。所以判斷是不是已經包含當然搜尋的節點在連結串列中,是用其中的數值陣列是不是完全相同來判斷的。

有界深度優先搜尋:

有界深度優先搜尋是在深度優先搜尋的基礎上進行的另一種對其深度進行限制的一種搜尋方法。當然其使用的資料結構也是和深度優先搜尋一樣的,其中的不同之處在於,在有界深度優先搜尋的基礎上判斷是不是相等時會有一個深度的同時相等的判斷,即只有當其中的陣列數值和搜尋深度同時相等時才認為是相等的。同時也會在深度達到5以後搜尋不會繼續發展更深的子節點,而是開始搜尋其兄弟節點等,然後繼續。如果找不到就返回“非常遺憾,沒有搜尋到你需要的目標!%>_<%”。

廣度(寬度)優先搜尋:

廣度優先搜尋,也被稱作寬度優先搜尋,是首先在兄弟節點之間進行搜尋和遍歷的方法,然後知道其全部的兄弟節點都已經遍歷完,才開始繼續往下發展其子節點,所以在這個過程中使用佇列(Queue介面的實現類LinkedList)來儲存其中還沒有遍歷的但是已經發展了的節點,同時使用連結串列來儲存已經搜尋過的子節點,然後基本上是和深度優先搜尋演算法類似。如果找不到就返回“非常遺憾,沒有搜尋到你需要的目標!%>_<%”。

【總結】

本次實驗利用圖的搜素演算法——深度優先搜尋、廣度優先搜尋、有界深度優先搜尋三種演算法完成八數碼問題的求解,利用Java程式設計語言程式設計,過程中遇到了諸多問題,以前太注重演算法這一塊的練習,實驗中,每一塊都是自己努力完成,也解決了遇到的問題,所以還是很有收穫的。