1. 程式人生 > >極大極小演算法轉

極大極小演算法轉

作者:知乎使用者
連結:https://www.zhihu.com/question/27221568/answer/140874499
來源:知乎
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
 

先來說極小極大演算法主要應用於什麼樣的遊戲:
1. 零和遊戲(Zero-sum Game):意思就是你死我活,一方的勝利代表另一方的失敗,比如,象棋,五子棋等。
2. 完全資訊(Perfect Information):玩家知道之前所有的步驟。象棋就是完全資訊,因為玩家是交替著落子,且之前的步驟都能在棋盤上體現,但是石頭剪子布就不是。
這樣的遊戲通常可以把他們看作一個樹狀圖,把每一種可能性列出來。比如下面這個井字棋遊戲,Max代表你自己,Min代表你的對手。

這個時候我們需要給每一種結果一個分數,就是這裡的Utility。這個分數是站在我自己(也就是Max)的角度評估的,比如上圖中我贏了就是+1,輸了是-1,平局時0。所以,我希望最大化這個分數,而我的對手希望最小化這個分數。(在遊戲中,這個分數被稱為static value。)這裡要說一下,井字棋是個比較簡單的遊戲,所以可以列出所有可能的結果。但是,大部分遊戲是不太可能把所有結果都列出來的。根據計算機運算量,我們可能只能往前推7,8步,所以這個時候分數就不只-1,1,0這麼簡單了,會有專門的演算法來根據當前結果給不同的分數。
假設我們有如下圖的遊戲,我是先手,我應該如何利用Minmax演算法來選出第一步怎麼走呢?

這個時候我們就要從結果看起,也就是第4步。圖中標註第四步是我的對手下的,所以他要做的是最小化這個分數,於是對手根據結果可以反推出如下選擇

繼續從後往前看到第3步,當我們知道了對手的選擇以後,我們可以根據對手的結果反推出自己的選擇,我們要做的是最大化這個分數,如圖

重複這個步驟,我們最終可以發現第一步的最優選擇,如圖

以上就是極小極大演算法(Minimax)。

 

當然對於一個複雜的遊戲來說,比如象棋,肯定是需要非常多步才能完成的。這就導致結果的數量是成幾何增長的,也就是說,如果這個遊戲每一步都有n個選擇,那麼在x步以後,將會有n^x個選擇。這個時候,我們就需要採取剪枝演算法(Alpha-Beta)來減少運算量。從剪枝演算法這個名字我們就能看出,這個演算法能讓我們剪掉樹狀圖中的一些分支,從而減少運算量。在這裡也說一下剪枝演算法,因為這並不是個不同於極小極大的演算法,而是極小極大演算法的升級版。
我們將遊戲簡化成如下圖,使用Minimax演算法,我們可以得出這樣的結果

但是,最後一步的分數其實也需要計算機來算(static evaluation),所以我們並不會一開始就有所有的資料,其實我們一開始是這樣的

然後,計算機給出了第一個分數

當給出了這個分數的時候,我們站在步驟1看,無論另一分支的數字是多少,步驟1左邊方框的數字不會超過2。因為第2步是我的對手下的,他希望分數儘可能的小,也就是這樣的

這個時候,電腦再計算另一分支的分數,也就是7。知道另一分數是7以後,也就知道步驟1的左邊方框分數為2。這時,我們往前看一步(步驟0)。步驟0的分數是大於等於2,因為我要最大化分數。如圖

現在,再來計算右邊分支的分數,得到了1。同理,我們站在步驟1來看,右邊方框中的數不會超過1,如圖

在這個情況下,即使我不算最後一個數字,我也能知道在步驟0的結果為2,因為已知步驟1中的右邊方框,數值不會超過1。所以我們就能直接知道結果,也就是


我們可以看到,加上剪枝演算法,我們不僅得到了相同的結果,而且減少了計算量。在實際應用中,加上剪枝演算法,計算機大約需要算2*n^(x/2)個結果,如果n為分支數,x為步數。相比於之前僅用極小極大演算法的n^x,效率提高了很多。這也就意味著,如果在象棋比賽中,假設使用極小極大的演算法,計算機能往前評估7步,加上剪枝演算法,計算機能往前評估14步。極小極大和剪枝演算法曾在IBM開發的國際象棋超級電腦,深藍(Deep Blue)中被應用,並且兩次打敗當時的世界國際象棋冠軍。