alpha-beta剪枝 个人理解

                                    alpha-beta剪枝

   首先看着代码是挺简单的,实现比较简单。但是其中思路确实还是比较饶人的。说白了就是,你在max层你要考虑min层他可能做出的选择,一般都是一层一层搜索的。有没有大牛给个搜索两层的代码? 首先假设你是max层,你要使得a(同阿尔法)最大,但是初始a是为最小,也就是啥都没有。你的对手如果站在你的角度他是b,他是使得b越小。为了保证你们两个是公平竞争,所以初始a是最小,你慢慢使他变大。初始b最大,对手慢慢使他变小,这样就解释了初始值的问题。

  好了解决了开始问题,问题基本就差不多解决了。这回我从min层开始讲,防止和其他人冲突。min根节点做出的选择,你要修改b使他慢慢变小,朝着你的目标前进。而你的答案是从下一层,也就是max层中 拿到最小的,而max层从下面min层搜索出一个最大的。由于算法是递归的,所以最后一层一定会返回会返回一个一般的答案。照图来看是只分析了三层,其实隔好几代剪枝也是成立的。

 我们假设这个答案是对你不有利的,那么max层一定会选择这一条。或者换种说法,max层做出的结果,肯定不会比当前更差,因为他总是选取最大的值。那么对于你min根节点来说,这条路就可以剪掉了,也就是b剪枝。为啥是b剪枝,而不是a剪枝呢? 因为对你根节点是min,搜的也是最小值,减少几个不必要的搜索分支。

 同理,根节点为max的a剪枝也就可以理解了。

  明白了什么是剪枝,我们在考虑一般情况。如图

 

 

下图从第二个max层开始分析,这个是函数的主体。虽然主节点是min,但是主节点并没有搜索的业务,只是被动选择最小的节点,可以说max层搜的结果固定,那么min也就是根节点的值一定是固定的。所以对于主体业务max层,他是寻找最大的,命名为int pro_max(int height, int a, int b)好像不太过分,但是其实是b剪枝(也就是会return 一个固定的b值)。

  好的 我们从max层分析,假设max层左边第一个节点搜索到了a值为8,(a表示max结果,有利于我方的,但是初始是最小,为了保证公平) 那么回溯过来根节点min的b值(b表示对方的最有利值,初始最大,保证公平),由于b是找最小,而8<∞,所以b,第一次更新为8。然后最左边的分支搜索结束,所有值都是确定的。然后开始max层中间搜索。这里的算法就是如果遇到,一个数比根节点的b值更大,或者相等。那么由于他的上一层是max层,那max肯定选择的不会比你搜索的值小。然而根节点是min层,你比根节点现在的值都要大,那么根节点肯定会舍弃。所以,我们在搜索max层的下一层,也即是第二层min,如果遇到一个比上两层的min层更大,那么直接舍弃。也就是b剪枝。

  好了讲到这里基本讲完了,差不多是我的理解。不会的话,我也没办法。我花了差不多一天时间才会,我想读者朋友们肯定比我聪明多了。我这基本都是白话文,大神轻喷。毕竟我只是个蒟蒻的菜鸡。

下面我给出b剪枝的算法 JAVA版本

public int pro_max_bCut(int height, int a, int b){

if(height == k)

return sum;//返回结果集合

for(int i =1; i<=3;i++){ //假设三个分支搜索,mm表示搜索集合

   sum+=mm[i];//这边sum只是模拟一下,并没有实际意思,只是要在这里算你想要的结果

   int val = pro_min_aCut(height+1, a, b);//这边是你想要搜索的, 然后需要每次传递a和b,这个要从下一层搜索出来。当前找最大,下一层就是找最小,没毛病。

 sum-=mm[i];//这边记得要回溯一下,不然结果只是一颗树的一个分支。为啥有的需要回溯,大概是因为sum是全局变量吧!

//下面就是根据搜索得出的val进行剪枝,先剪枝可以优化代码

if(val >= b)

   return b;//b剪枝,可以直接返回这个搜索树得出结果

if(val >a)

   a=val; //这里是找出最大的,a保存最大的值

}

return a;//循环结束,给出自己的最大值,就是这个找最大的函数

}

那个 a剪枝,道理差不多 可以把a b 换一下,然后写出来,这里就不重复了。 就是>= 变为 <= return b 变为return a。如果明白了我上面说的,就可以写的出来。不会的话,嘿嘿,同志仍需努力啊。 

基本就是这个意思,没有测试能不能跑,因为没有具体题目。思路对了就好。这边如果是搜索可以给出启发式搜索,可以快一点得出结果。启发式函数可以在 {sum+=mm[i];//这边sum只是模拟一下,并没有实际意思,只是要在这里算你想要的结果} 这个代码前面进行编写,目的是尽可能快速得出结果,就是优先生成可以产生结果的树,个人观点有点像贪心,都是不一定保证结果是对的,只是理论可能是对的。

 

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值