⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 高级搜索方法——简介(二).htm

📁 象棋程序设计全资料集(介绍编写象棋程序的方法思路)
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0056)http://www.elephantbase.net/computer/advanced_intro2.htm -->
<HTML><HEAD><TITLE>高级搜索方法——简介(二)</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb_2312-80">
<META content="" name=Owner>
<META content="" name=Reply-To>
<META content="MSHTML 6.00.3790.2817" name=GENERATOR></HEAD>
<BODY background=高级搜索方法——简介(二)_files/background.gif>
<DL>
  <DIV align=center>
  <CENTER>
  <DT>《对弈程序基本技术》专题 </CENTER></DT></DIV>
  <DIV align=center>
  <CENTER>
  <DT>  </CENTER></DT></DIV>
  <DIV align=center>
  <CENTER>
  <DT><FONT face=Arial size=6><STRONG>Alpha-Beta</STRONG></FONT><FONT face=隶书 
  size=6>搜索的诸多变种</FONT> </CENTER></DT></DIV>
  <DIV align=center>
  <CENTER>
  <DT>  </CENTER></DT></DIV>
  <DIV align=center>
  <CENTER>
  <DT><FONT face="Times New Roman">David Eppstein */</FONT>文 
</CENTER></DT></DIV>
  <DIV align=center>
  <CENTER>
  <DT><FONT face="Times New Roman">* </FONT>加州爱尔文大学<FONT 
  face="Times New Roman">(UC Irvine)</FONT>信息与计算机科学系 </CENTER></DT></DIV>
  <DIV align=center>
  <CENTER>
  <DT>  </CENTER></DT></DIV>
  <DT><FONT size=3>  尽管我们已经讨论过</FONT><FONT face="Times New Roman" 
  size=3>Alpha-Beta</FONT><FONT 
  size=3>搜索简单有效,还是有很多方法试图更有效地对博弈树进行搜索。它们中的大部分思想就是,如果认为介于</FONT><FONT 
  face="Times New Roman" size=3>Alpha</FONT><FONT size=3>和</FONT><FONT 
  face="Times New Roman" size=3>Beta</FONT><FONT 
  size=3>间的评价是感兴趣的,而其他评价都是不感兴趣的,那么对不感兴趣的评价作截断会让</FONT><FONT 
  face="Times New Roman" size=3>Alpha-Beta</FONT><FONT 
  size=3>更有效。如果我们把</FONT><FONT face="Times New Roman" size=3>Alpha</FONT><FONT 
  size=3>和</FONT><FONT face="Times New Roman" size=3>Beta</FONT><FONT 
  size=3>的间距缩小,那么感兴趣的评价会更少,截断会更多。</FONT> 
  <DT>  首先让我们回顾一下原始的<FONT face="Times New Roman">Alpha-Beta</FONT>搜索,忽略散列表和“<A 
  href="http://www.elephantbase.net/computer/other_winning.htm" 
  target=_blank>用当前层数调整胜利值</A>”的细节。 
  <DT>  
  <DD>// 基本的Alpha-Beta搜索 
  <DD>int alphabeta(int depth, int alpha, int beta) { 
  <DD> move bestmove; 
  <DD> if (棋局结束 || depth &lt;= 0) { 
  <DD>  return eval(); 
  <DD> } 
  <DD> for (每个合理着法 m) { 
  <DD>  执行着法 m; 
  <DD>  score = -alphabeta(depth - 1, -beta, -alpha); 
  <DD>  if (score &gt;= alpha) { 
  <DD>   alpha = score; 
  <DD>   bestmove = m; 
  <DD>  } 
  <DD>  撤消着法 m; 
  <DD>  if (alpha &gt;= beta) { 
  <DD>   break; 
  <DD>  } 
  <DD> } 
  <DD> return alpha; 
  <DD>} 
  <DT>  
  <DT><FONT face=楷体_GB2312 size=5><STRONG>超出边界</STRONG></FONT><FONT face=Arial 
  size=5><STRONG>(Fail-Soft)</STRONG></FONT><FONT face=楷体_GB2312 
  size=5><STRONG>的</STRONG></FONT><FONT face=Arial 
  size=5><STRONG>Alpha-Beta</STRONG></FONT> 
  <DT>  
  <DT>  以上代码总是返回<FONT face="Times New Roman">Alpha</FONT>、<FONT 
  face="Times New Roman">Beta</FONT>或在<FONT 
  face="Times New Roman">Alpha</FONT>和<FONT 
  face="Times New Roman">Beta</FONT>之间的数。换句话说,当某个值不感兴趣时,从返回值无法得到任何信息。原因就是当前值被变量<FONT 
  face="Times New Roman">Alpha</FONT>所保存,它从感兴趣的值的窗口下沿开始一直增长的,没有可能返回比<FONT 
  face="Times New Roman">Alpha</FONT>更小的值。一个对<FONT 
  face="Times New Roman">Alpha-Beta</FONT>的简单改进就是把当前评价和<FONT 
  face="Times New Roman">Alpha</FONT>分开保存。下面的伪代码用常数“<FONT 
  face="Times New Roman">WIN</FONT>”表示最大评价,它可以在<FONT 
  face="Times New Roman">Alpha-Beta</FONT>搜索中返回任何评价。 
  <DT>  
  <DD>// 超出边界的Alpha-Beta搜索 
  <DD>int alphabeta(int depth, int alpha, int beta) { 
  <DD> move bestmove; 
  <DD> int current = -WIN; 
  <DD> if (棋局结束 || depth &lt;= 0) { 
  <DD>  return eval(); 
  <DD> } 
  <DD> for (每个可能的着法 m) { 
  <DD>  执行着法 m; 
  <DD>  score = -alphabeta(depth - 1, -beta, -alpha); 
  <DD>  撤消着法 m; 
  <DD>  if (score &gt;= current) { 
  <DD>   current = score; 
  <DD>   bestmove = m; 
  <DD>   if (score &gt;= alpha) { 
  <DD>    alpha = score; 
  <DD>   } 
  <DD>   if (score &gt;= beta) { 
  <DD>    break; // <FONT 
  color=#0000ff>【译注:这里可以直接返回score、current或alpha,如果返回beta,则是不会高出边界的Alpha-Beta搜索。】</FONT> 

  <DD>   } 
  <DD>  } 
  <DD> } 
  <DD> return current; 
  <DD>} 
  <DT>  
  <DT>  这样改动以后,就可以知道比以前稍多一点的信息。如果返回值<FONT 
  face="Times New Roman"><EM>x</EM></FONT>等于或小于<FONT 
  face="Times New Roman">Alpha</FONT>,我们仍然不知道局面的确切值<FONT 
  face="Times New Roman">(</FONT>因为我们可能在搜索中裁剪了一些线路<FONT 
  face="Times New Roman">)</FONT>,但是我们知道确切值最多是<FONT 
  face="Times New Roman"><EM>x</EM></FONT>。类似地,如果<FONT 
  face="Times New Roman"><EM>x</EM></FONT>大于或等于<FONT 
  face="Times New Roman">Beta</FONT>,我们就知道搜索值至少是<FONT 
  face="Times New Roman"><EM>x</EM></FONT>。这些微小的上界和下界变化不会影响搜索本身,但是它们能导致散列表命中率的提高。超出边界的<FONT 
  face="Times New Roman">Alpha-Beta</FONT>搜索对下面要介绍的<FONT 
  face="Times New Roman">MTD(<EM>f</EM>)</FONT>算法有重要作用。 
  <DT>  
  <DT><FONT face=楷体_GB2312 size=5><STRONG>期望搜索</STRONG></FONT> 
  <DT>  
  <DT>  这个方法不是代替<FONT 
  face="Times New Roman">Alpha-Beta</FONT>的,只是从外部改边一个途径来调用搜索过程。通常用<FONT 
  face="Times New Roman">Alpha-Beta</FONT>找最好路线时,可以调用: 
  <DD>  
  <DD>alphabeta(depth, -WIN, WIN) 
  <DT>  
  <DT>  这里 <FONT face=Symbol>-</FONT><FONT face="Times New Roman">WIN </FONT>和 
  <FONT face="Times New Roman">WIN 
  </FONT>之间的范围很大,表明我们不知道搜索值是多少,因此任何可能的值都必须考虑。随后,要走的那步保存在搜索函数外部的变量中。 
  <DT>  期望搜索的不同之处在于,我们可以人为地指定一个狭窄窗口<FONT 
  face="Times New Roman">(</FONT>用前一个搜索值为中心<FONT 
  face="Times New Roman">)</FONT>,对搜索通常是有帮助的。如果你搜索失败,必须加宽窗口重新搜索: 
  <DT>  
  <DD>// 期望搜索 
  <DD>int alpha = previous - WINDOW; 
  <DD>int beta = previous + WINDOW; 
  <DD>for ( ; ; ) { 
  <DD> score = alphabeta(depth, alpha, beta); 
  <DD> if (score &lt;= alpha) { 
  <DD>  alpha = -WIN; 
  <DD> } else if (score &gt;= beta) { 
  <DD>  beta = WIN; 
  <DD> } else { 
  <DD>  break; 
  <DD> } 
  <DD>} 
  <DT>  
  <DT>  权衡狭窄搜索所节约的时间,和因为失败而重新搜索的时间,可以决定常数 <FONT face="Times New Roman">WINDOW 
  </FONT>的大小。在国际象棋中,典型的值也许是半个兵。期望搜索的变体有,搜索失败时适当增加窗口宽度,或者用初始窗口而没必要以前一次搜索结果为中心,等等。 

  <DT>  
  <DT><FONT face=Arial 
  size=5><STRONG>MTD(</STRONG><EM><STRONG>f</STRONG></EM><STRONG>)</STRONG></FONT> 

  <DT>  
  <DT>  这个技术跟期望搜索一样,只是在调用<FONT 
  face="Times New Roman">Alpha-Beta</FONT>时对初始值进行调整。搜索窗口越窄搜索就越快,这个技术的思想就是让搜索窗口尽可能的窄:始终用“<FONT 
  face="Times New Roman">beta = alpha + 1</FONT>”来调用<FONT 
  face="Times New Roman">Alpha-Beta</FONT>。用这样一个“零宽度”搜索的作用是用<FONT 
  face="Times New Roman">Alpha</FONT>和确切值作比较:如果搜索的返回值最多是<FONT 
  face="Times New Roman">Alpha</FONT>,那么确切值本身最多是<FONT 
  face="Times New Roman">Alpha</FONT>,相反确切值大于<FONT 
  face="Times New Roman">Alpha</FONT>。 
  <DT>  我们可以用这个思想对确切值作二分搜索: 
  <DT>  
  <DD>int alpha = -WIN; 
  <DD>int beta = +WIN; 
  <DD>while (beta &gt; alpha + 1) { 
  <DD> int test = (alpha + beta) / 2; 
  <DD> if (alphabeta(depth, test, test + 1) &lt;= test) { 
  <DD>  beta = test; 
  <DD> } else { 
  <DD>  alpha = test + 1; 
  <DD> } 
  <DD>} 
  <DT>  
  <DT>  但是,这样会导致大规模的搜索<FONT face="Times New Roman">(</FONT>即 <FONT 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -