中国象棋人机对弈搜索算法学习-极大极小值,负极大值,alpha-beta算法
2016-04-07 18:48
417 查看
先参考学习如下博文:
/article/2733706.html
http://hk.gamfe.com/news/201502/2170.html
参考图书《PC游戏编程(人机博弈)》
负极大值法 依然是 极大极小值法,只是多了个负号。博弈树中父结点的值 是 其子节点的 负最大值。即 黑方取最大,红方取 负最大,这样比较最大就行了。代码要比极大极小值法要好简洁一些。
实现时,需要用变量保存每一次移动情况,DFS中只需要拥有一个最大深度的数组即可。结束时,取数组的第一个移动,作为当前的最好移动。
口袋的例子
比如你的死敌面前有很多口袋,他和你打赌赌输了,因此他必须从中给你一样东西,而挑选规则却非常奇怪:
每个口袋里有几件物品,你能取其中的一件,你来挑这件物品所在的口袋,而他来挑这个口袋里的物品。你要赶紧挑出口袋并离开,因为你不愿意一直做在那里翻口袋而让你的死敌盯着你。
假设你一次只能找一只口袋,在找口袋时一次只能从里面摸出一样东西。
很显然,当你挑出口袋时,你的死敌会把口袋里最糟糕的物品给你,因此你的目标是挑出“诸多最糟的物品当中是最好的”那个口袋。
你很容易把最小-最大原理运用到这个问题上。你是最大一方棋手,你将挑出最好的口袋。而你的死敌是最小一方棋手,他将挑出最好的口袋里尽可能差的物品。运用最小-最大原理,你需要做的就是挑一个有“最好的最差的”物品的口袋。
假设你可以估计口袋里每个物品的准确价值的话,最小-最大原理可以让你作出正确的选择。我们讨论的话题中,准确评价并不重要,因为它同最小-最大或Alpha-Beta的工作原理没有关系。现在我们假设你可以正确地评价物品。
最小-最大原理刚才讨论过,它的问题是效率太低。你必须看每个口袋里的每件物品,这就需要花很多时间。
那么怎样才能做得比最小-最大更高效呢?
我们从第一个口袋开始,看每一件物品,并对口袋作出评价。比方说口袋里有一只花生黄油三明治和一辆新汽车的钥匙。你知道三明治更糟,因此如果你挑了这只口袋就会得到三明治。事实上只要我们假设对手也会跟我们一样正确评价物品,那么口袋里的汽车钥匙就是无关紧要的了。
现在你开始翻第二个口袋,这次你采取的方案就和最小-最大方案不同了。你每次看一件物品,并跟你能得到的最好的那件物品(三明治)去比较。只要物品比三明治更好,那么你就按照最小-最大方案来办——去找最糟的,或许最糟的要比三明治更好,那么你就可以挑这个口袋,它比装有三明治的那个口袋好。
比方这个口袋里的第一件物品是一张20美元的钞票,它比三明治好。如果包里其他东西都没比这个更糟了,那么如果你选了这个口袋,它就是对手必须给你的物品,这个口袋就成了你的选择。
这个口袋里的下一件物品是六合装的流行唱片。你认为它比三明治好,但比20美元差,那么这个口袋仍旧可以选择。再下一件物品是一条烂鱼,这回比三明治差了。于是你就说“不谢了”,把口袋放回去,不再考虑它了。
无论口袋里还有什么东西,或许还有另一辆汽车的钥匙,也没有用了,因为你会得到那条烂鱼。或许还有比烂鱼更糟的东西(那么你看着办吧)。无论如何烂鱼已经够糟的了,而你知道挑那个有三明治的口袋肯定会更好。
我:我的接受程度有下限,给我的太差,我肯定不干。
对方: 我肯定给你相对最差的,但是我无法确定每个口袋究竟有哪些物品,我不希望出现某个口袋好东西很多,我可给不起。
参考学习:http://www.cnblogs.com/speeding/archive/2012/09/20/2694704.html
百度百科:Alpha-Beta算法
/article/2733706.html
http://hk.gamfe.com/news/201502/2170.html
参考图书《PC游戏编程(人机博弈)》
极大极小值法
深度搜索(dfs)伪代码/** 1。 p 为棋盘 2。 d 为规定的搜素最大深度,比如d层红方,d-1层为黑方,d-2层为红方...依此类推,可采用mod2来判断当前是哪一方 4。评估棋盘的函数evaluation,当然需要看是哪一方,若红方为机器,黑方为人,那么机器(红方)做为极大(INF),人作为极小(-INF),让机器选择最合适的一步。 **/ int MiniMax(chessmap p , int d) { int bestvalue , value ; if( Game Over )// 如果游戏结束 return evaluation(p); if(depth <= 0) // 如果已经到了搜索树叶子结点 return evaluation(p); if( d % 2 == RED) //轮到红方 bestvalue = - INF; else bestvalue = INF ; for(each possible move m) { MakeMove(m) ; //产生第i个局面(子节点),p会相应变化 value = MiniMax(p,d-1);//递归 UnMakeMove(m) ; // 恢复p if(d % 2 == RED) bestvalue = max(value ,bestvalue);//取最大 else bestvalue = max(value ,bestvalue);//取最小 } return bestvalue; }
负极大值法:
负极大值法 依然是 极大极小值法,只是多了个负号。博弈树中父结点的值 是 其子节点的 负最大值。即 黑方取最大,红方取 负最大,这样比较最大就行了。代码要比极大极小值法要好简洁一些。
实现时,需要用变量保存每一次移动情况,DFS中只需要拥有一个最大深度的数组即可。结束时,取数组的第一个移动,作为当前的最好移动。
Alpha-beta搜索算法
好好学习:http://www.xqbase.com/computer/search_alphabeta.htm口袋的例子
比如你的死敌面前有很多口袋,他和你打赌赌输了,因此他必须从中给你一样东西,而挑选规则却非常奇怪:
每个口袋里有几件物品,你能取其中的一件,你来挑这件物品所在的口袋,而他来挑这个口袋里的物品。你要赶紧挑出口袋并离开,因为你不愿意一直做在那里翻口袋而让你的死敌盯着你。
假设你一次只能找一只口袋,在找口袋时一次只能从里面摸出一样东西。
很显然,当你挑出口袋时,你的死敌会把口袋里最糟糕的物品给你,因此你的目标是挑出“诸多最糟的物品当中是最好的”那个口袋。
你很容易把最小-最大原理运用到这个问题上。你是最大一方棋手,你将挑出最好的口袋。而你的死敌是最小一方棋手,他将挑出最好的口袋里尽可能差的物品。运用最小-最大原理,你需要做的就是挑一个有“最好的最差的”物品的口袋。
假设你可以估计口袋里每个物品的准确价值的话,最小-最大原理可以让你作出正确的选择。我们讨论的话题中,准确评价并不重要,因为它同最小-最大或Alpha-Beta的工作原理没有关系。现在我们假设你可以正确地评价物品。
最小-最大原理刚才讨论过,它的问题是效率太低。你必须看每个口袋里的每件物品,这就需要花很多时间。
那么怎样才能做得比最小-最大更高效呢?
我们从第一个口袋开始,看每一件物品,并对口袋作出评价。比方说口袋里有一只花生黄油三明治和一辆新汽车的钥匙。你知道三明治更糟,因此如果你挑了这只口袋就会得到三明治。事实上只要我们假设对手也会跟我们一样正确评价物品,那么口袋里的汽车钥匙就是无关紧要的了。
现在你开始翻第二个口袋,这次你采取的方案就和最小-最大方案不同了。你每次看一件物品,并跟你能得到的最好的那件物品(三明治)去比较。只要物品比三明治更好,那么你就按照最小-最大方案来办——去找最糟的,或许最糟的要比三明治更好,那么你就可以挑这个口袋,它比装有三明治的那个口袋好。
比方这个口袋里的第一件物品是一张20美元的钞票,它比三明治好。如果包里其他东西都没比这个更糟了,那么如果你选了这个口袋,它就是对手必须给你的物品,这个口袋就成了你的选择。
这个口袋里的下一件物品是六合装的流行唱片。你认为它比三明治好,但比20美元差,那么这个口袋仍旧可以选择。再下一件物品是一条烂鱼,这回比三明治差了。于是你就说“不谢了”,把口袋放回去,不再考虑它了。
无论口袋里还有什么东西,或许还有另一辆汽车的钥匙,也没有用了,因为你会得到那条烂鱼。或许还有比烂鱼更糟的东西(那么你看着办吧)。无论如何烂鱼已经够糟的了,而你知道挑那个有三明治的口袋肯定会更好。
我:我的接受程度有下限,给我的太差,我肯定不干。
对方: 我肯定给你相对最差的,但是我无法确定每个口袋究竟有哪些物品,我不希望出现某个口袋好东西很多,我可给不起。
参考学习:http://www.cnblogs.com/speeding/archive/2012/09/20/2694704.html
百度百科:Alpha-Beta算法
相关文章推荐
- (Caffe)基本类DataReader、QueuePair、Body(四)
- 线程同步的几种方式
- +(void)load与+(void)initialize
- Oracle字符串分割Split(超简单一条sql解决)
- CGOS461 [网络流24题] 餐巾(最小费用最大流)
- python-摩尔斯电码查询器
- 网页中嵌套百度地图
- PL/SQL Developer 中文字段显示乱码
- git 切换到远程分支
- 802.1x+AD+DHCP+NPS动态下发vlan Windows Server 2008端配置
- HBase高级特性:通过Coprocessor实现Solr Cloud二级索引
- stl -- 适配器
- python3.4 x86_64-linux-gnu-gcc Error
- 深度剖析ConcurrentHashMap(转)
- Docker基础技术:Linux Namespace(下)
- [乱搞] BZOJ 2296 [POJ Challenge] 随机种子
- android学习之网络连接2
- swustOJ 1615寻宝
- android中listview最后一个item没有下横线的原因?
- Android高级UI之ViewPager实现页卡的最新方法-简洁的TabLayout