AI-隨機迷宮&迷宮求解

來源:互聯網
上載者:User

標籤:

本文記錄了,人工智慧中簡單的搜尋策略中的路徑搜尋策略中的A*演算法,來實現迷宮尋路的問題.(這隻是一次本人的課外作業)

完整的程式源碼已經發送到我的Git.這裡只記錄了我的思路和感想以及收穫.

產生隨機迷宮

迷宮求解沒有迷宮怎麼可以呢.而本人是個懶人,每次都要手動輸入迷宮,重複性的工作讓我很不爽.你可以在程式中用數組定義一個迷宮啊,有強迫症的我,怎麼可以這樣隨便的要求自己的程式呢.及時求解演算法的出來了,但是測試資料有限,還是讓我很不爽的,所以,乾脆先花一些時間,寫個隨機迷宮的產生吧.

遇事先搜尋,看看前輩有沒有經驗分享,站在前輩的肩膀上,你可以少走很多彎路.

本人搜尋到一篇論文:基於圖的深度遍曆產生隨機迷宮的演算法研究,看了以後,發現論文中有很多的錯誤,而且演算法也不簡潔,有很多地方完全可以非常簡化的,但是非要寫的那麼複雜,生怕別人可以看懂似得.所以,就按照自己的理解,簡單的實現了隨機迷宮的產生.

參考,紅色(起始位置),綠色(終點位置).而我產生隨機迷宮的方法簡單,產生的迷宮有一定的局限性.,從起始位置(最左上方)開始,每次隨機的選取當前節點的右邊或下邊的節點作為擴充的節點.順便還要判斷一下下一個結點是否越界.通過這種方法會產生一條從矩形的一個點到另一個點的最短路徑,該條路徑是沒有迴路的路徑,就這樣,當隨機播放出一條路徑以後,其餘的點任意擺布,是牆是路都可以,最終我們一定會得到一條最短的路徑,我的簡單隨機迷宮誕生了.

至於更加完善的隨機迷宮的產生,以後有時間了再學習一下.

A*演算法遍曆

如果在這裡介紹這個演算法,我感覺太沒意思了.人工智慧的學習還是有視頻或者專人的講授比較好,看書真的很枯燥的.這裡我只說實現的過程中的困難和想法以及收穫.

A*演算法中重要的由2張表,open表和close表.

open表存放的都是沒有擴充的節點,而且表裡的內容(fn=gn+hn)是按照從小到大排序的。

close表存放的都是已經擴充過的節點,也就說已經遍曆過的節點,這表裡的節點中就存在著最終的路徑。

A*演算法先是利用open表和close表找到最終的目標節點,然後倒序從close表裡依次把以前遍曆過的路徑節點找出來,即可得到完整的路徑。

就想所示的簡單迷宮一樣,開始的時候,會同時擴充右邊和下面的節點,存入open表裡,然後選擇open表中f最小的值,而在這個例子中,選擇的是下面的方塊,所以就這樣沿著紅色箭頭的方向一直擴充下去,直到,發現open表中的2個節點有10和12,這時候,才調轉方向,拋棄12,選擇10((0,1)節點)繼續開始新的遍曆(藍色箭頭的方向),最終找到終點。

找到終點以後,圖中的陰影的結點都在close表裡面,然後,我們發現路徑中的g從終點到起點是倒序的,h則是升序的。我們就利用這個特性來實現路徑的輸出。g=10的下一個節點的特徵是(g=g-1&&節點是相鄰的)根據這個判斷,我們就會很容易的倒序找到完整的路徑了。詳細的實現的方法參見代碼。

我的收穫

花費了一周的時間來實現這個功能,使用的C++語言,而且中間也遇到了不少的困難。當你遇到的困難實在想不起好的解決方案的時候,那麼不妨先放下,做其他的事情.晚上睡覺的時候,或者吃放走路洗澡的時候,腦子裡想想就可以了.解決問題的關鍵是在一瞬間想起來的,實在不行的時候,不妨讓大腦放鬆一下,不必心急火燎,容易上火.

bug(1)

堆棧的溢出:以前寫程式的時候沒有遇到過這種問題,曾經都使用過上萬的資料空間,也沒有出現過問題,但是這次的二維數組QT上面使用23*23,也就是迷宮的長和寬就出現這種情況了。長和寬23*23,那麼頂點總共529個,轉化為邊的關係則有529*529=279841,額,確實有點大。解決方案很簡單,定義成全域變數或者結構裡面使用指標,函數裡面使用動態malloc記憶體配置,就OK了。

bug(2)

翻譯過來就是算數異常,這個bug直到現在我也沒有解決,因為不妨礙我程式的運行,這個bug只在程式調試的時候才出現。如下:

大家知道程式調試的環境和啟動並執行環境是不一樣的,就那Qt來說吧,啟動並執行時候MinGW,而調試的時候是GDB,根據圖示,這裡應該出現了k=0的情況,random產生的隨機數的範圍是0~k-1所以,出錯了。我是這麼想的,也可能錯了,如有見解,請指點。關於這次的程式,使我的GDB也崩潰了,害得我還重新安裝了QT。

bug(3)

參考資料這麼說的:出現了Segmentation fault,基本上的原因是,非法的記憶體訪問。例如數組的越界,在迴圈操作時迴圈變數的控制問題,也有字串拷貝時間長度度溢出,指標指向了非法的空間,還有就是申明一個指標,但卻沒有對其初始化,就直接引用,或者沒有開闢記憶體空間就釋放記憶體,所以要檢查申請空間時間的成功。

編程習慣的改進:

說實話程式大了,代碼多了,有時候就不在意良好的編程習慣了。這次在遇到bug的時候,請教了QQ群的網友,雖說最終的問題沒有解決,但是,給我提了不少寶貴的建議。

(1)變數的使用和定義盡量額緊湊,靠在一起。

(2)最重要的也就是這一句:不要在判斷語句中使用有副作用的語句。何為副作用?會改變程式狀態的語句。如下:

if(getchar()==‘Y‘||getchar()==‘y‘){}

getchar()從緩衝區讀取一個字元,讀一個少一個,那麼讀的過程中程式的狀態是不是改變了?

好的寫法如下:

char ch=toupper(getchar());if(‘Y‘==ch){}

學習的道路艱巨而漫長.

AI-隨機迷宮&迷宮求解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.