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

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

ima 基本 個數 博弈論 數字 這就是 pre -- 繼續

極大極小搜索,即minimax搜索算法,專門用來做博弈論的問題的暴力.

多被稱為對抗搜索算法.

這個搜索算法的基本思想就是分兩層,一層是先手,記為a,還有一層是後手,記為b.

這個搜索是認為這a與b的利益關系是對立的,即假設a要是分數更大,b就要是分數更小.

而且這兩個人都是用最優策略.

對,就是這樣.

假設我們現在有一道題,給出一串數列,有兩個選手按順序選數,也就是一個選手選了ai,接下來另一個選手就必須選ai後面的任意一個數,然後每個選手選的數的累加和即為選手的分數,求先手比後手最多多幾分.(兩個選手都會選擇最優策略)

保證序列裏所有的數為正數.

那麽我們可以設計一個算法:

先手的框架為:枚舉上一次另一個選手選的數字後面開始選,取最大值.

後手的框架為:枚舉上一次另一個選手選的數字後面開始選,取最小值.

即:

 1 int dfsb(int k){
 2   int minn=1000000000;
 3   for (int i=k;i<=n;i++)      //枚舉接下來的要取的數 
 4     minn=min(minn,dfsa(i+1)-a[i]);      //搜索接下來對b最優的結果,也就是分數最小 
 5   minn=min(minn,0);      //考慮不取的情況 
 6   return minn;      //返回最優策略的得分 
7 } 8 int dfsa(int k){ 9 int maxx=-1000000000; 10 for (int i=k;i<=n;i++) //枚舉接下來的要取的數 11 maxx=max(maxx,a[i]+dfsb(i+1)); //搜索接下來對a最優的結果,也就是分數最大 12 maxx=max(maxx,0); //考慮不取的情況 13 return maxx; //返回最優策略的得分 14 }

接下來是一個對於對抗搜索的最佳搭檔——alpha-beta優化.

這個優化的思想很簡單,即對於a來說,需要的是最大值,而下面的b取得是最小值.

而接下來如果b的已求出的最小值比a的已求出的最大值小,還有必要繼續搜嗎?

同樣的,對於b來說,需要的是最小值,而下面的b取得是最大值.

於是這就是alpha-beta剪枝.

具體實現如下:

 1 int dfsb(int k,int maxx){      //多傳一個maxx值表示上一層已經求出的最大值 
 2   int minn=1000000000;
 3   for (int i=k;i<=n;i++) {      //枚舉接下來的要取的數 
 4     minn=min(minn,dfsa(i+1,minn)-a[i]);      //搜索接下來對b最優的結果,也就是分數最小 
 5     if (minn<maxx) return;      //alpha-beta優化 
 6   }
 7   minn=min(minn,0);      //考慮不取的情況 
 8   return minn;      //返回最優策略的得分 
 9 }
10 int dfsa(int k,int minn){      //多傳一個minn值表示上一層已經求出的最小值 
11   int maxx=-1000000000;
12   for (int i=k;i<=n;i++) {      //枚舉接下來的要取的數
13     maxx=max(maxx,a[i]+dfsb(i+1,maxx));      //搜索接下來對a最優的結果,也就是分數最大 
14     if (maxx>minn) return;      //alpha-beta優化 
15   }
16   maxx=max(maxx,0);      //考慮不取的情況 
17   return maxx;      //返回最優策略的得分 
18 }

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