關於做人工智慧—五子棋的總結

來源:互聯網
上載者:User

前言

   剛學玩C一個月,院裡有個程式設計的比賽,於是就動手寫了這玩意兒。

本文:

    首先,對於每一盤棋都有很多種下法,當黑方落下第一顆棋子的時候,白方有254種下法,白方在這254種下法中選擇其一後,黑方又有253中下法。如此,將所有的下法都考慮,全部列出來就構成了一顆巨大的博弈樹,也稱搜尋數。這顆博弈樹的根節點便是黑方下的第一顆棋子,緊接著的下一層便是白方下棋的所有情況,依次下去,直到結束。而電腦要做的是從下面的子節點中找出最有利於電腦方的節點,也就是最佳走法。誰想得深遠,預測的步數越多,棋局瞭解到位,就越厲害。如果能將未來的所有情況都考慮到位,那必定處於不敗之地。

    在選擇最佳走法中,我們要用到極小極大搜尋演算法。我們先假設有個對棋局的評價函數,即可以對任何一個局面對電腦方打分,分越高越對電腦有利,分越低卻對玩家有利,也就是說這個評價函數是對電腦方而言的,電腦贏則為無窮大,輸則無窮小。其它所有情況都在這之間。

如上圖就是所謂的博弈樹,假如:甲對應電腦方,乙對應玩家。當前該電腦方下棋,即甲0節點,下一層的子節點即該玩家下。雙方都希望在未來的局勢中,往最有利於己方的方向進行。電腦當然想自己的分高,所以會選子節點分值最大的乙1,分值為2,所以甲0分值為2。而乙1想分值低,於是,他會選甲3-4中分值最小的甲3,分值為2,乙1的值因此為2。所以,在極小極大搜尋演算法中,稱想要最大值的甲的節點為極大值點,想要最小值的乙的節點為極小值點。在這個極大值極小值的搜尋過程為極小極大搜尋演算法。

    前面所說的,都是理論上可行的方法,因為在這複雜度指數級增長的過程中,想要搜尋完這麼龐大的博弈樹是不可能的。我們只能往後預測幾步,就用靜態估值函數算出分數,然後一步步反向推算上去,而到當前最佳的走法。這時,我們就需要一個對任意局面評分的評價函數。如果給評估函數打分呢。我是把把棋面分成72路,橫15 + 豎15 + 左斜21 + 右斜21 = 72(因為斜著的共有16路形成不了五子)。為72路是為了收集具有形成5子可能性的特徵。一個棋局具有電腦方的這些特徵越多,棋局分數便越高,具有玩家方特徵越多,分值便越低,因此玩家的特徵是記負分的。當然不同的特徵分值也不同。我將電腦方棋子抽象為1,空格抽象為0。例如:遇到11111便賦值9999999,011110賦值300000,011100或001110賦值為3000等等。如果是玩家的棋就賦相應的負分。最後把72路的分數加起來,黑白雙方的總分相加就得到整個棋局的分數。其實,我把每一路的情況分成一個個長度為6的字串,一一跟原來預定的16個特徵做比較,留下每一路分值最大的特徵。然而,在沒一次判斷下那一步的時候,要預測的情況數是巨大的,而沒一種情況都要調用靜態估值函數,進行大概7000次特徵的匹配。為了減少匹配的次數,我用了哈夫曼樹編碼的思想,把所有的特徵編成了一個哈夫曼樹(如下圖,當時的草稿),每個節點都由0、1組成,這也是我之前把棋子抽象為1,空格抽象為0的原因。具體就不在詳述,哈夫曼樹編碼的思想我是參考的《演算法與資料結構》151頁。如此,每一個長度為6個字元就不必跟16個特徵一一線性比較,這樣就大大的減少了計算量。

    光憑上面的還遠遠不夠,我實驗過,僅預測三步的時候,電腦下一步,需要等待近半個小時。因此,我在極小極大搜尋演算法中還加入了Alpha-Beta剪枝剪枝法,可以叫它為Alpha-Beta搜尋演算法。如下圖:

上述的極小極大值搜尋過程中,遍曆了整棵的博弈樹,每一個節點都訪問了一次,這樣的搜尋演算法粗糙,效率低下,搜尋量非常大。假如將分葉節點的評估,計算反向推算值與樹的產生同時進行,就可能大量減少所需搜尋的節點數目,而且保持搜尋效果不變。具體思路如下:

Alpha剪枝:

如圖:極大值點甲3及下面所有節點

1.因為乙7為2,因此甲三大於或等於2;

2.甲19為1,則乙8小於或等於1;

3.既然甲2是取最大的,暫且等於2,就不用考慮小於或等於1的乙 8了。

  因此,甲20不需要考慮,把它剪掉。

Beta剪枝:

同理,如圖:極小值點乙1及下面所有節點,一樣分析。

這樣,就減少了不少分支,剪掉的分部,既不用建立合法的走法,也不用在評估時大量的計算,在一定程度上最佳化了許多。但是,Alpha-Beta剪枝剪枝法在減枝過程搜尋效率與節點的排列順序有很大關係。因此,可以在產生走法的時候對它進行排序來達到進一步的最佳化。按理說,對極小節點按從小到大的順序排序,對極大節點按從大到小的順序排序是最理想的,但是在最後的節點沒產生之前,不可能得到評估值。所以,排序的時候可以根據威脅性大的點周圍進行優先搜尋的辦法達到最佳化的效果。

    最後便是我在最後兩天想出來的最佳化辦法,在開頭的幾十步裡,它的最佳化效果比Alpha-Beta剪枝剪枝法好上幾十倍。這裡我用到的是縮小搜尋範圍演算法,其實是我瞎起的一個名字。前面的Alpha-Beta剪枝剪枝法是在產生一定子節點後剪掉部分枝節而達到最佳化效果,而縮小搜尋範圍演算法則是從根節點處直接砍掉分支,從頂端砍下來的話,完全捨棄了其下龐大的分支。具體思路如下:我們在下棋的時候,基本都是在已有的棋子周圍下子,所以還有很多空位是完全不需要搜尋的。就是基於這一點,我們就能可以確定搜尋範圍,先判斷已下了的棋子最大對角線,在此對角線的基礎上畫矩形,然後在向外圍擴大一兩格,這樣就在根節點上減少了分支,更不需要考慮在其範圍外的以後幾步的情況了。不過,在預測的過程中,我們要假設下了某子,這些預測的下子會很快的將範圍擴大到邊界,而當預測完一個父節點及以下子節點的所有情況後,與前面父節點同一深度的節點並不需要那麼大的搜尋範圍,因此理想的搜尋範圍應和預測前同樣的。這裡,我們可以採用堆棧的結構,用入棧操作就可將一方下的棋子存入棧中,得到新的搜尋範圍,當搜尋過程的回溯發生時用出棧操作退出一子,即可恢複到前一搜尋範圍。這樣就能步步為營,有進有退,儘可能的減少不必要的計算。

展望未來:

   前面講的改進搜尋演算法的目標在於將不必搜尋的(冗餘)分枝從搜尋的過程中盡量剔除,以達到盡量搜尋少的分枝束降低運算量的目的。但是仍然在有限時間內預測幾步而已,想要讓電腦達到世界級水平還是不夠的。開頭我提過中原大學的碩士學位論文《五子棋棋略的演化學習法》中核心講的“基因演算法”,也稱遺傳演算法,是讓程式具有學習功能,在大量的實踐中,程式會不段的更改評估函數特徵的權值,這樣便克服了人為主觀因素的片面性。而在啟發學習法搜尋過程中,其實有很多局面是重複的,就增加了很多不必要的重複計算,為瞭解決這個問題,可以使用基於雜湊表的置換表搜尋演算法,將搜尋過的局面存如資料,不需要了就清除,遇到相同的局面只需調用前面計算得出的資料,就避免重算。另外,現在的超執行緒技術和多核技術也能達到進一步的最佳化。

感想:

    這此做人工智慧五子棋,多少也有點收穫,相對以前更加懂得怎麼在有限的時間內完成自己看似不可能或很難完成的任務,此類任務最好的方法便是證比求易。當中肯定有自己不曾具備的知識,當處於當今這個時代,我們需要的這點知識還是很輕易的找到。然而最關鍵的還是自己以最快的方法消化弄懂它,讓前人或大師研究過的寶貴成果迅速成為自己的技能。作為一名程式員,這次經曆給我的感受是,完成一個程式,最重要的絕對是演算法,這此做五子棋,人工智慧模組的演算法我也弄了幾天才搞清楚,也許只有某一個點有疑惑,它也可以讓你一個下午也弄不明白。當演算法完成之後,就可以立即開始組織編碼,從資料結構入手,理清程式流程,然後把各個子模組一一攻破。演算法花了幾天,而編碼一天內便能完成,我們日後的重點也因在構思這塊。碼農於軟體工程師的共同點是都會編程,而軟體工程師之所以不同是因為他能以程式化思想解決問題本身,而編碼是碼農們的事了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.