谈极小化极大值搜索
在人工智能的機器博弈中首先學習的就是極小極大值搜索Minimax,有人翻譯成Minmax,少寫了中間的字母i,感覺意思不夠準確。Minimax的含義就是極小化對手的最大利益。
維基百科中給出的偽代碼如下:http://www.cnblogs.com/pangxiaodong/archive/2011/05/26/2058864.html 加上了中文翻譯。
function minimax(node, depth) // 指定當前節(jié)點和搜索深度 // 如果能得到確定的結果或者深度為零,使用評估函數(shù)返回局面得分 if node is a terminal node or depth = 0 return the heuristic value of node // 如果輪到對手走棋,是極小節(jié)點,選擇一個得分最小的走法 if the adversary is to play at node let α := +∞ foreach child of node α := min(α, minimax(child, depth-1)) // 如果輪到我們走棋,是極大節(jié)點,選擇一個得分最大的走法 else {we are to play at node} let α := -∞ foreach child of node α := max(α, minimax(child, depth-1)) return α;?
我實現(xiàn)的C++代碼:
// 返回值是搜索的評估值,board是當前的局面// 這里30000是紅方取勝的局面,-30000是黑方取勝的局面int MiniMaxSearch(int depth) { // 所謂確定的結果,在象棋里就是被將死的情況
// 當著法生成中已經有了將軍的判斷,下面這幾行的if else是不需要的
// 因為如果某方被將死了,n_moves將等于0,說明產生不出合法的著法,此時就直接返回-30000或30000了if (board.WhichTurn == TURN_BLACK && board.IsCheckmated()) { return -30000; } else if (board.WhichTurn == TURN_RED && board.IsCheckmated()) { return +30000; } if (depth == 0) return Evaluate(board); // 搜索達到指定深度時int bestValue = (board.WhichTurn == TURN_RED) ? -30000 : 30000;Move move_list[256]; int n_moves;n_moves = GenerateAllMoveList( board, move_list );for(int i=0; i<n_moves; i++) { board.MakeMove(move_list[i]); // 走一著棋 int value = MiniMaxSearch(depth - 1); board.UnmakeMove(move_list[i]); // 撤消一著棋 if (board.WhichTurn == TURN_RED) // 極大節(jié)點 bestValue = (value > bestValue)? value : bestValue; else // 極小節(jié)點 bestValue = (value < bestValue) ? value: bestValue; } return bestValue; }
在這個網站有一個java applet可以用圖示的方式清晰地演示minimax和alphabeta剪枝的運行過程。 http://ksquared.de/gamevisual/launch.php?agent=2
?
NegaMax的算法更簡潔:
但要注意:NegaMax中的評估函數(shù),對輪到誰走棋是敏感的。
例如:
在MiniMax中,輪紅方走棋時,假如評估值為100,輪黑方走棋評估值仍是100。
但在NegaMax中,輪紅方走棋時,假如評估值為100,輪黑方走棋時評估值要為-100。
1 int Search::NegaMax(int depth, int maxDepth) 2 { 3 /* 在著法生成中有將軍的判斷,這里就不需要再進行判斷了。否則還要進行終止局面的判斷。 4 */ 5 6 if (depth == maxDepth) return Eval::Evaluate(board); 7 8 int bestScore = -30000 + depth; //這種寫法可以搜索最好的殺著 9 10 Move moveList[256]; 11 int countMoves; 12 13 // 著法生成中要進行將軍的判斷,也就是輪到紅方走棋時,紅方的走完后,帥不能被將軍 14 countMoves = MoveGenerator::GenerateAllMoveList( board, moveList ); 15 16 for(int i=0; i<countMoves; i++) 17 { 18 board.MakeMove(moveList[i]); 19 int score = -NegaMax(depth + 1, maxDepth); 20 board.UnmakeMove(moveList[i]); 21 bestScore = (score > bestScore)? score : bestScore; 22 } 23 return bestScore; 24 }?
?
?
?
?
轉載于:https://www.cnblogs.com/speeding/archive/2012/09/17/2689337.html
總結
- 上一篇: display:block的注意
- 下一篇: 敏捷开发-测试