1. 程式人生 > >[演算法] 極大極小搜尋

[演算法] 極大極小搜尋

原文連結: http://www.xqbase.com/computer/search_minimax.htm總結兩點:1. 深度優先搜尋,只有在葉子節點計算評估分。
2. max和min層只負責從分支中,選擇最大或者最小的評分。


《對弈程式基本技術》專題
最小-最大搜索
Bruce Moreland / 
 從淺顯的地方開始   在國際象棋裡,雙方棋手都知道每個棋子在哪裡,他們輪流走並且可以走任何合理的著法。下棋的目的就是將死對方,或者避免被將死,或者有時爭取和棋是最好的選擇。  國際象棋程式通過使用“搜尋”函式來尋找著法。搜尋函式獲得棋局資訊,然後尋找對於程式一方來說最好的著法。  一個淺顯的搜尋函式用“樹狀搜尋”(Tree-Searching)
來實現。一個國際象棋棋局通常可以看作一個很大的n叉樹(n叉樹”意思是樹的每個結點有任意多個分枝通向其他結點),棋盤上目前的局面就是“根局面”(Root Position)或“根結點”(Root Node)。從根局面走一步棋,局面就到達根局面的“分枝”(Branch),這些局面稱為“後續局面”(Successor Position)或“後續結點”(Successor Nodes)。每個後續局面後面還有一系列分枝,每個分枝就是這個局面的一個合理的著法。  國際象棋的樹非常龐大(通常每個局面有35個分枝),又非常深。  每盤棋局都是一棵巨大的n叉樹,如果能通過樹狀搜尋找到棋局中對雙方來說都最好的著法就好了。這個淺顯的演算法在這裡稱為“最小-
最大搜索”(Min-max Search)。  用最小-最大搜索來解諸如井字棋的簡單棋局是可行的(即完全瞭解每一種變化)。井字棋的博弈樹既不煩瑣也不深,所以整個樹可以遍歷,棋局的所有變化都可以知道,任何局面都可以保證找到一步最佳著法。  數學上用這種方法處理國際象棋也是可以的,但是目前和不久的將來用計算機去實現,卻是不可行的。即便如此,我們仍然可以用基於最小-最大搜索的程式來下國際象棋。相比最小-最大地搜尋整個樹,在一個給定的局面下搜尋前幾步則是可能的。由於葉子結點的局面沒能搜尋出殺棋或和棋,所以要用一個稱為“評價”(Evaluate)的啟發函式給這些局面賦值。儘管程式設計師希望這些值能夠通過知識來得到,但它們確實都是猜的。 基於最小-最大的評價函式
   我不打算在這裡談很多關於評價函式的細節。這裡我只說明它是怎樣確定的,在以後的章節中會詳細展開。評價函式首先應該返回局面的準確值,在沒辦法得到準確值的情況下,如果可能的話啟發值也可以。它可以由兩種方法來決定:  (1) 如果黑方被將死了,那麼評價函式返回一個充分大的正數;如果白方被將死了,那麼返回一個充分大的負數;如果棋局是和棋(例如某一方逼和,或者雙方都只有王),那麼返回一個常數,通常是零或接近零。如果不是棋局結束局面,那麼它返回一個啟發值。我將不詳細介紹這個啟發值是如何確定的,但是我有把握說子力平衡是首先要考慮的(如果白方盤面上多子的話,這個值就大),而其他位置上的考慮(兵型、王的安全性、重要的子力等等)也需要加上。如果白方是贏棋或者很有希望贏,那麼啟發函式通常會返回正數;如果黑方是贏棋或者很有希望贏,那麼返回負數;如果棋局是均勢或者是和棋,那麼返回在零左右的數值。  (2) 這個函式的工作原理跟第一個一樣,只是如果當前局面要走子的一方優勢,那麼它返回正數,反之是負數。 最小-最大搜索是如何運作的   最小-最大搜索是一對幾乎一樣的函式,或者說兩個邏輯上重複的函式。我寫了很少的程式碼,用一個更好的函式來完成同一件事,但是寫出來時卻收到一些意見,因此我首先寫出純粹的(不完美的)最小-最大函式,程式碼如下: int MinMax(int depth) { if (SideToMove() == WHITE) { // 白方是“最大”者  return Max(depth); } else {           // 黑方是“最小”者  return Min(depth); }} int Max(int depth) { int best = -INFINITY; if (depth <= 0) {  return Evaluate(); } GenerateLegalMoves(); while (MovesLeft()) {MakeNextMove();  val = Min(depth - 1);UnmakeMove();  if (val > best) {   best = val;  } } return best;} int Min(int depth) { int best = INFINITY; // 注意這裡不同於“最大”演算法 if (depth <= 0) {  return Evaluate(); } GenerateLegalMoves(); while (MovesLeft()) {  MakeNextMove();  val = Max(depth - 1);  UnmakeMove();  if (val < best) {  // 注意這裡不同於“最大”演算法   best = val;  } } return best;}   上面的程式碼可以這樣呼叫: val = MinMax(5);   這樣可以返回當前局面的評價,它是向前看5步的結果。  這裡的“評價”函式用的是我上面所說第一種定義,它總是返回對於白方來說的局面。  我簡要描述一下這個函式是如何運作的。假設根局面(棋盤上當前局面)是白方走,那麼呼叫的是“Max”函式,它產生白方所有合理著法。在每個後續局面中,呼叫的是“Min”函式,它對局面作出評價並返回。由於現在是白走,因此白方需要讓評價儘可能地大,能得到最大值的那個著法被認為是最好的,因此返回這個著法的評價。  “Min”函式正好相反,當黑方走時呼叫“Min”函式,而黑方需要儘可能地小,因此選擇能得到最小值的那個著法。  這兩個函式是互相遞迴的,即它們互相呼叫,直到達到所需要的深度為止。當函式到達最底層時,它們就返回“Evaluate”函式的值。  如果在深度為1時呼叫“MinMax”函式,那麼“Evaluate”函式在走完每個合理著法之後就呼叫,選擇一個能達到最佳值的那個著法導致的局面。如果層數大於1,那麼另一方有權選擇局面,並找一個最好的。  以上內容應該不難理解,但是程式碼很長,下面有個更好的辦法。 負值最大函式   負值最大隻是對最小-最大的優化,“評價”函式返回我所說的第二種定義,對於當前結點上要走的一方,佔優的情況返回正值,其他結點也是對於要走的一方而言的。這個值返回後要加上負號,因為返回以後就是對另一方而言了。程式碼如下: int NegaMax(int depth) { int best = -INFINITY; if (depth <= 0) {  return Evaluate(); } GenerateLegalMoves(); while (MovesLeft()) {  MakeNextMove();  val = -NegaMax(depth - 1); // 注意這裡有個負號。  UnmakeMove();  if (val > best) {   best = val;  } } return best;}   在這個函式裡,當走子一方改變時就要對返回值取負值,以反映當前局面評價的更改。就根結點是白先走的情況,如果沒有剩下的層數,那麼“評價”返回的值是就白方而言的,如果有剩下的層數,就產生後續局面,函式對這些局面逐一做遞迴,每個次遞迴都得到就黑方而言的評價,黑方走得越好值就越大。當評價值返回時,它們被取負數,變成就白方而言的評價。  該函式在遍歷時結點的順序同“最小-最大”搜尋的函式是一樣的,產生的返回值也一樣。它的程式碼更短,同時減少了移植程式碼時出錯的可能,程式碼維護起來也比較方便。   原文:http://www.seanet.com/~brucemo/topics/minmax.htm  譯者:象棋百科全書網 ([email protected])  型別:全譯

相關推薦

[演算法] 極大搜尋

原文連結: http://www.xqbase.com/computer/search_minimax.htm總結兩點:1. 深度優先搜尋,只有在葉子節點計算評估分。 2. max和min層只負責從分支中,選擇最大或者最小的評分。《對弈程式基本技術》專題 最小-最大

極大搜尋和阿爾法貝塔剪枝搜尋演算法的簡單描述與理解--萌新向通俗易懂

這是本人第一次正經寫部落格,排版技術不行,看起來可能有點難受,但我相信如果大家認真按順序讀下去一定能理解這個演算法,如果還有不是很清楚或者覺得我哪裡有講錯的地方歡迎評論留言!這段時間都在!會看和回覆的! 阿爾法貝塔剪枝是基於極大極小值搜尋的一種演算法。 舉個比較簡單的例子

【LeetCode 913】cat-and-mouse | BFS+記憶化 | 極大搜尋+AB剪枝 | CGUZ | H

【難題警告!】 核心:BFS + 記憶化(標程) /  極大極小搜尋 + alpha-beta剪枝(近似解) Difficulty : Hard     Discuss (32) ACCEPTED  1,341          SUBMISSIONS  6

博弈基礎——極大搜尋

        計算機博弈(也稱機器博弈),是一個挑戰無窮、生機勃勃的研究領域,是人工智慧領域的重要研究方向,是機器智慧、兵棋推演、智慧決策系統等人工智慧領域的重要科研基礎。機器博弈被認為是人工智慧領

CCF 201803-4 棋局評估 極大搜尋

題意:3X3的井字棋,1先走,2後走,給定一個狀態。當前輪到1走,1,2都按照最優策略行棋,求最後的分數。 #include <cstdio> #include <algorithm

MATLAB—一字棋(極大搜尋

init.m %初始化棋盤狀態 function cur=init() cur=rand(3,3); %儲存當前棋盤的狀態 %計算機為先手時的初值,即均為0 for i=1:3 for j=1:3 cur(i,j)=0;

poj 1085 Triangle War 1568 Find the Winning Move 極大搜尋 alpha-beta剪枝

一,極大極小搜尋及alpha-beta剪枝(參考這裡) 在博弈搜尋中,比如:圍棋,五子棋,象棋等,結果有三種可能:勝利,失敗和平局。 理論上可以窮舉所有的走法,這就需要生成整棵博弈樹。實際上不可行。因此搜尋時可以限制博弈樹的深度,到達該深度則不再往下搜,相當

POJ 1085 Triangle War(極大搜尋+alpha-beta剪枝)

// // main.cpp // Richard // // Created by 邵金傑 on 16/8/29. // Copyright © 2016年 邵金傑. All rights reserved. // #include<iostream&g

POJ 1085 Triangle War(博弈,極大搜尋+alpha_beta剪枝)

題目:給出10個點,總共有18條邊,每次兩個人輪流加入一條邊,如果形成一個三角形,則三角形歸他所有,而且可以額外再走一步。最後三角形多的人勝 博弈問題 所謂的極大極小搜尋,其實就是搞個估價函式。然後主角肯定選個估價函式最大的,即對自己最有利的局面走。 而輪到對方的時候,

201803-4棋局評估_極大演算法_對抗搜尋(轉載)

問題描述 試題編號:201803-4 試題名稱:棋局評估 時間限制:1.0s 記憶體限制:256.0MB 問題描述:問題描述  Alice和Bob正在玩井字棋遊戲。   井字棋遊戲的規則很簡單

中國象棋人機對弈搜尋演算法學習-極大值,負極大值,alpha-beta演算法

極大極小值法 深度搜索(dfs)虛擬碼 /** 1。 p 為棋盤 2。 d 為規定的搜素最大深度,比如d層紅方,d-1層為黑方,d-2層為紅方...依此類推,可採用mod2來判斷當前是哪一方 4。評估棋盤的函式evaluation,當然需要看

五子棋(人機)-極大搜尋演算法

從人落子開始到出現勝負或者和局,之間所落的子,構成了一個解。而解空間就是一個樹,解就是這解空間中的一條路徑。只不過這個解空間是電腦的選擇和人的選擇共同構成的(奇數層是電腦(因為輪到電腦落子麼),偶數層是人)。 極大極小值搜尋演算法,來搜尋(回溯)這個解空間:它假設人和電腦都

極大演算法

作者:知乎使用者 連結:https://www.zhihu.com/question/27221568/answer/140874499 來源:知乎 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。   先來說極小極大演算法主要應用於什麼樣的遊戲: 1. 零和遊戲(

極大搜尋 + 剪枝

/* 題意: Alice和Bob玩遊戲,在一個4x4 的方格上 每個人每次選擇2x2的區域將裡面的四個值求和加到最後的分數當中(兩個人共用一個分數), 然後逆時針翻轉它們, Alice想要分數儘量大Bob想要分數儘量小 兩個人每次的選擇都是最優的,求最後的分數

極大演算法原理

參考書籍《人工智慧基礎教程》 該演算法的搜尋策略是考慮雙方若干步之後,從可能的步中選擇相對較好的走發來走。 以MAX表示程式方,MIN表示對手方,P表示局勢,f(P)是根據當前局勢做出的估計函式。 則 F(p)>0表示對MAX有利的局勢 F(p)<0表示對MI

QT五子棋專案詳解之四:AI人機對戰max-min極大值博弈演算法

不考慮博弈的演算法怎麼能算是AI呢?max-min極大極小值演算法就是考慮了博弈的演算法。來看一個簡單的例子在這個棋局中,電腦為白旗,白旗走哪一步更好呢,也許使用策略表會告訴你,應該衝4,但是衝4後,玩家就會連成4。這就是考慮了博弈之後,這一步棋就是敗局。這就是為什麼有max

極大搜索思想+(α/β)減枝 【轉自-----https://blog.csdn.net/hzk_cpp/article/details/79275772】

ima 基本 個數 博弈論 數字 這就是 pre -- 繼續 極大極小搜索,即minimax搜索算法,專門用來做博弈論的問題的暴力. 多被稱為對抗搜索算法. 這個搜索算法的基本思想就是分兩層,一層是先手,記為a,還有一層是後手,記為b. 這個搜索是認為這a與b的利益關

算法筆記--極大搜索及alpha-beta剪枝

cor article posit oss else hab alt 葉子節點 知乎 參考1:https://www.zhihu.com/question/27221568 參考2:https://blog.csdn.net/hzk_cpp/article/details

牛頓法求極大

牛頓法至少有兩個應用方向,1、求方程的根,2、最優化。牛頓法涉及到方程求導,下面的討論均是在連續可微的前提下討論。 1、求解方程。 並不是所有的方程都有求根公式,或者求根公式很複雜,導致求解困難。利用牛頓法,可以迭代求解。 原理是利用泰勒公式,在x0處展開,且展開

1568 Find the Winning Move 極大搜尋+alpha-beta剪枝

題目:在一個4*4的格子裡面,x和o兩個人玩遊戲,x畫'x',o畫'o',x先手,給定x和o都已經畫了一定步數的局面,問x是不是必勝的,如果是,輸出他應該畫在哪個位置 思路:極小極大搜尋+alpha-beta剪枝 程式碼: #pragma comment(linker, "