<转>博弈相关

来源:互联网 发布:郎咸平 离婚 知乎 编辑:程序博客网 时间:2024/04/30 09:03
博弈算法之alpha-beta搜索 收藏 
   博弈一向被认为是最富挑战的智力游戏,有着难以言语的魅力。自从出现计算机后人们就开始有了与计算机下棋的想法。早在上世纪60年代就已经出现若干博弈程序,并达到较高的水平,现已出现计算机博弈程序能够与人类博弈大师抗衡的局面。博弈理论的研究不断为人类科学提供新的课题,同时也对深层次的知识研究提出了严峻的挑战。如何表示博弈问题的状态,博弈过程和取胜的知识是目前人类仍在探讨的问题。就拿五子棋游戏来讲,棋面有15×15 = 225 个落子点,对方走完一步后,计算机差不多有200多种选择每一种选择对应搜索树的一个节点,即棋局上的一个状态。计算机走完一步后就应该考虑对方会走哪一步,此时同样有200种选择,因此有200×200种可能的选择,对应搜索分支达到200×200个,如果博弈程序要考虑20回合,搜索树就有40层,总结点大约有10^92 个。这个数字即使是计算机以每秒万亿次的速度计算,走一步棋也要一年。因此提高博弈问题的求解程序效率,因该做到以下两点:
1,改进生产过程,使之只产生好的节点,即选择比较好的节点去扩展。
2,改进测试过程,使最好的步骤能够及时被确认,确认的代价不能太大。
   目前博弈论比较常用的的搜索策略有极大极小搜索策略,深度优先的alpha-beta剪枝搜索等。本文仅讨论极大极小搜索策略和深度优先的alpha-beta剪枝搜索策略。
一,极大极小值搜索
    极大极小值搜索始终站在博弈一方的立场上给棋局估值,有利于这一方的棋局给一个较高的评价值,不利于这一方(有利于另一方)的给予一个较低的评价值,双方优劣不明显的局面给予一个中间评价值(一般是0)本方行棋的时候选择评价值极大的节点走步,另一方行棋时则选择评价值极小的子节点走步。这就是一个极大极小的过程。基本思想如下:当轮到对手走棋时应考虑最坏的情况;当轮到自己走棋时应考虑最好的情况;当评价往回倒退时,相应于两位棋手的对抗策略,在不同层次上交替使用前两种方法往回传递倒退值。下面举例详细说明。
    假如A,B两位棋手行棋,B棋手落子后现在轮到A棋手落子,A棋手经过分析发现目前有三个落子点P1,P2,P3为最优落子点,于是A棋手分别对三个落子点进行分析以确定最好的一个落子点。开始对P1进行分析,当在P1落子点落子后棋手B会按照与棋手A相同的博弈思想选择一个对己方最有利的落子点假设为Q1,当Q1落子后A棋手就会对棋局评分,假设为40分;按同样的方法分析P2与P3点,假设与P2,P3相对应的Q2,Q3落子后棋局的评分分别为50分,30分。经过以上分析棋手A可以得出结论,P1,P2,P3三个落子点中P2为最优落子点,因为在P2落子点落子后即使对手在对我方最不利的落子点落子我方的评分是50分,而其他两种落子点却是30和40(这里棋局对A棋手的有利程度与分数成正比).采用极大极小搜索策略的博弈程序使计算机与棋手A有相同的分析过程。
二,深度优先的alpha-beta搜索
   在极大极小搜索的过程中存在着一定的数据冗余,提出这些冗余数据是减小搜索空间的必然做法,所采用的方法就是1975年Monroe Newborn 提出的alpha-bete剪枝。
    把alpha-bete剪枝应用到极大极小搜索中就形成了alpha-bete搜索。
    若任一极小层节点的bete值小于或等于他任一先辈节点的alpha值,则可终止该极小层中该MIN节点一下的搜索过程,这个MIN节点最终的倒退值就确定为bete值。这一过程就称为alpha剪枝。
    若任一极大层节点的alpha值大于或等于他任一先辈极小层节点的bete值,则可终止该MAX节点以下的搜索过程,这个MAX节点的最终倒退值就确定为alpha值。这一过程就称为bete剪枝。
    为了使整个过程更加清晰依然以上面的例子说明alpha-bete搜索过程。
    假如A棋手在P2落子点落子后B棋手经过分析得到三个对己方最有利的节点,分别是Q2a,Q2b,Q2c。因此有以下三种情况:A棋手选择P2节点落子,B棋手选择Q2a节点落子;A棋手选择P2节点落子,B棋手选择Q2b节点落子;A棋手选择P2节点落子,B棋手选择Q2c节点落子。根据这三种情况A棋手分别对棋局进行评分,如果第一种情况下棋局的得分为35分,那么A棋手就可以不必分析后两种情况的棋局得分而直接得出p1节点比P2节点好的结论。这样一来A棋手就可以迅速从三个最好落子点中排除P2落子点,对于计算机来说就节省了CPU时间。因为A棋手把B棋手想像的足够聪明,B棋手会选择Q2a,Q2b,Q2c三个落子点中对A棋手最不利的一个节点,所以只要以上三种情况中有一种情况的棋局得分比P1落子点小那么P1落子点就比P2落子点优秀。从以上分析中我们可以看到alpha-bete搜索对节点的排列非常敏感对于同一层上的节点如果排列合适剪枝效率就很高,可以使实际搜索的博弈树达到最小树。
    这里给出alpha-bete搜索的java代码实现。
    极大值搜索过程:
    protected int findMax(int alpha,int beta,int step){
  int mx = alpha;//极大最小值;
  if(step == 0){ //达到特定深度返回;
   return evaluate();
  }
  //循环调用findmin,找出当前节点对应的最大值;
  for(int i = 3;i<11;i++){
   for(int j = 3;j<11;j++){//搜索范围为3×11;
    if(chess[i][j] ==0){
     if(getType(i,j,startbw)==1)//getTepy()得到当前棋局的棋型;
      return 100*getMark(1);//getMark()返回特定棋型的得分;
     chess[i][j] = startbw;
     
     int t = findMin(mx,beta,step-1);//调用极小值搜索;
     chess[i][j] = 0;
     if(t > mx)
      mx = t;//搜索极大值;
     if(mx >= beta)//beta剪枝;
      return mx;//退出搜索;
    }
   }
  }
  return mx;
 }
 
 
    极小值搜索过程:
 protected int findMin(int alpha,int beta,int step){
  int mn = beta;//极小最大值;
  if(step == 0){
   return evaluate();
  }
  int[][] rt = getBests(3-startbw);//返回部分最优解;
  for(int i = 0;i<rt.length;i++){
   int ii = rt[i][0];
   int jj =rt[i][1];
   if(getType(ii,jj,3-startbw)==1)
    return  -100*getMark(1);
   chess[ii][jj]= 3-startbw;
   int t = findMax(alpha,mn,step-1);
   chess[ii][jj]=0;
   if(t < mn)
    mn=t;
   if(mn <= alpha)//alpha 剪枝;
    return mn;
  }
  return mn;
 }