📌  相关文章
📜  博弈论中的极小极大算法设置1(简介)

📅  最后修改于: 2021-04-26 09:11:02             🧑  作者: Mango

Minimax是一种回溯算法,用于决策和博弈论中,假设您的对手也玩得很尽善尽美,可以为玩家找到最佳移动。它广泛用于两个基于回合的玩家游戏,例如井字游戏,五子棋,曼卡拉,国际象棋等。
在Minimax中,这两个播放器分别称为最大化器和最小化器。最大化器尝试获得可能的最高分,而最小化器尝试进行相反的操作并获得可能的最低分。
每个板状态都有一个与之关联的值。在给定状态下,如果最大化器占了上风,那么木板的分数将趋于某个正值。如果最小化器在该板状态下处于优势地位,那么它将趋向于为负值。棋盘的价值是通过一些启发式方法计算得出的,这些启发式方法对于每种类型的游戏都是唯一的。
例子:
考虑一个具有4个最终状态的游戏,达到最终状态的路径是从完美二叉树的根到4个叶子的路径,如下所示。假设您是最大的玩家,并且您有第一个机会移动,即,您位于根源,而您的对手处于下一个级别。考虑到您的对手也发挥了最佳表现,您将作为一名最大化的球员采取哪一步?

博弈论Minimax算法

由于这是基于回溯的算法,因此它将尝试所有可能的移动,然后回溯并做出决定。

  • 最大化器左移:现在是最小化器转向。最小化器现在可以在3到5之间选择。作为最小化器,它肯定会在两者中选择最少的一个,即3
  • 最大化器向右:现在是最小化器了。最小化器现在可以在2到9之间进行选择。他将选择2,因为它是两个值中最小的一个。

作为最大化器,您将选择较大的值3。因此,最大化器的最佳移动方向为LEFT,最佳值为3。
现在,游戏树如下所示:

博弈论极小极大算法1

上面的树显示了最大化器左右移动时的两个可能得分。
注意:即使右侧子树上的值为9,最小化器也永远不会选择该值。我们必须始终假设我们的对手发挥最佳。
下面是相同的实现。

C++
// A simple C++ program to find
// maximum score that
// maximizing player can get.
#include
using namespace std;
 
// Returns the optimal value a maximizer can obtain.
// depth is current depth in game tree.
// nodeIndex is index of current node in scores[].
// isMax is true if current move is
// of maximizer, else false
// scores[] stores leaves of Game tree.
// h is maximum height of Game tree
int minimax(int depth, int nodeIndex, bool isMax,
            int scores[], int h)
{
    // Terminating condition. i.e
    // leaf node is reached
    if (depth == h)
        return scores[nodeIndex];
 
    //  If current move is maximizer,
    // find the maximum attainable
    // value
    if (isMax)
       return max(minimax(depth+1, nodeIndex*2, false, scores, h),
            minimax(depth+1, nodeIndex*2 + 1, false, scores, h));
 
    // Else (If current move is Minimizer), find the minimum
    // attainable value
    else
        return min(minimax(depth+1, nodeIndex*2, true, scores, h),
            minimax(depth+1, nodeIndex*2 + 1, true, scores, h));
}
 
// A utility function to find Log n in base 2
int log2(int n)
{
  return (n==1)? 0 : 1 + log2(n/2);
}
 
// Driver code
int main()
{
    // The number of elements in scores must be
    // a power of 2.
    int scores[] = {3, 5, 2, 9, 12, 5, 23, 23};
    int n = sizeof(scores)/sizeof(scores[0]);
    int h = log2(n);
    int res = minimax(0, 0, true, scores, h);
    cout << "The optimal value is : " << res << endl;
    return 0;
}


Java
// A simple java program to find maximum score that
// maximizing player can get.
 
import java.io.*;
 
class GFG {
   
 
// Returns the optimal value a maximizer can obtain.
// depth is current depth in game tree.
// nodeIndex is index of current node in scores[].
// isMax is true if current move is of maximizer, else false
// scores[] stores leaves of Game tree.
// h is maximum height of Game tree
 static int minimax(int depth, int nodeIndex, boolean  isMax,
            int scores[], int h)
{
    // Terminating condition. i.e leaf node is reached
    if (depth == h)
        return scores[nodeIndex];
 
    // If current move is maximizer, find the maximum attainable
    // value
    if (isMax)
    return Math.max(minimax(depth+1, nodeIndex*2, false, scores, h),
            minimax(depth+1, nodeIndex*2 + 1, false, scores, h));
 
    // Else (If current move is Minimizer), find the minimum
    // attainable value
    else
        return Math.min(minimax(depth+1, nodeIndex*2, true, scores, h),
            minimax(depth+1, nodeIndex*2 + 1, true, scores, h));
}
 
// A utility function to find Log n in base 2
 static int log2(int n)
{
return (n==1)? 0 : 1 + log2(n/2);
}
 
// Driver code
 
    public static void main (String[] args) {
            // The number of elements in scores must be
    // a power of 2.
    int scores[] = {3, 5, 2, 9, 12, 5, 23, 23};
    int n = scores.length;
    int h = log2(n);
    int res = minimax(0, 0, true, scores, h);
    System.out.println( "The optimal value is : "  +res);
         
    }
}
 
// This code is contributed by vt_m


C#
// A simple C# program to find maximum score that
// maximizing player can get.
using System;
 
public class GFG
{
     
// Returns the optimal value a maximizer can obtain.
// depth is current depth in game tree.
// nodeIndex is index of current node in scores[].
// isMax is true if current move is of maximizer, else false
// scores[] stores leaves of Game tree.
// h is maximum height of Game tree
static int minimax(int depth, int nodeIndex, bool isMax,
            int []scores, int h)
{
    // Terminating condition. i.e leaf node is reached
    if (depth == h)
        return scores[nodeIndex];
 
    // If current move is maximizer, find the maximum attainable
    // value
    if (isMax)
    return Math.Max(minimax(depth+1, nodeIndex*2, false, scores, h),
            minimax(depth+1, nodeIndex*2 + 1, false, scores, h));
 
    // Else (If current move is Minimizer), find the minimum
    // attainable value
    else
        return Math.Min(minimax(depth+1, nodeIndex*2, true, scores, h),
            minimax(depth+1, nodeIndex*2 + 1, true, scores, h));
}
 
// A utility function to find Log n in base 2
static int log2(int n)
{
    return (n==1)? 0 : 1 + log2(n/2);
}
 
// Driver code
static public void Main ()
{
 
    // The number of elements in scores must be
    // a power of 2.
    int []scores = {3, 5, 2, 9, 12, 5, 23, 23};
    int n = scores.Length;
    int h = log2(n);
    int res = minimax(0, 0, true, scores, h);
    Console.WriteLine( "The optimal value is : " +res);
     
}
}
 
// This code is contributed by ajit.


Python3
# A simple Python3 program to find
# maximum score that
# maximizing player can get
import math
 
def minimax (curDepth, nodeIndex,
             maxTurn, scores,
             targetDepth):
 
    # base case : targetDepth reached
    if (curDepth == targetDepth):
        return scores[nodeIndex]
     
    if (maxTurn):
        return max(minimax(curDepth + 1, nodeIndex * 2,
                    False, scores, targetDepth),
                   minimax(curDepth + 1, nodeIndex * 2 + 1,
                    False, scores, targetDepth))
     
    else:
        return min(minimax(curDepth + 1, nodeIndex * 2,
                     True, scores, targetDepth),
                   minimax(curDepth + 1, nodeIndex * 2 + 1,
                     True, scores, targetDepth))
     
# Driver code
scores = [3, 5, 2, 9, 12, 5, 23, 23]
 
treeDepth = math.log(len(scores), 2)
 
print("The optimal value is : ", end = "")
print(minimax(0, 0, True, scores, treeDepth))
 
# This code is contributed
# by rootshadow


Javascript


输出:

The optimal value is:  12

本文的目的是通过一个简单的示例介绍Minimax。

  • 在上面的示例中,玩家只有两个选择。通常,可以有更多选择。在这种情况下,我们需要重复所有可能的移动并找到最大值/最小值。例如,在井字游戏中,第一个玩家可以进行9个可能的动作。
  • 在上面的示例中,分数(游戏树的叶子)被提供给我们。对于典型的游戏,我们需要导出这些值