五子棋AI 算法——极大极小搜索
2017-12-02 13:39
344 查看
计算机博弈(也称机器博弈),是一个挑战无穷、生机勃勃的研究领域,是人工智能领域的重要研究方向,是机器智能、兵棋推演、智能决策系统等人工智能领域的重要科研基础。机器博弈被认为是人工智能领域最具挑战性的研究方向之一。
机器博弈的核心技术是博弈搜索算法
零和博弈(zero-sum game),又称零和游戏,与非零和博弈相对,是博弈论的一个概念,属非合作博弈。指参与博弈的各方,在严格竞争下,一方的收益必然意味着另一方的损失,博弈各方的收益和损失相加总和永远为“零”,双方不存在合作的可能。
也可以说:自己的幸福是建立在他人的痛苦之上的,二者的大小完全相等,因而双方都想尽一切办法以实现“损人利己”。零和博弈的结果是一方吃掉另一方,一方的所得正是另一方的所失,整个社会的利益并不会因此而增加一分。
----------------------------------------------------------------------------------------------------------------------------------------------------
最单纯的极大极小算法
局面估价函数:我们给每个局面(state)规定一个估价函数值 f,评价它对于己方的有利程度。胜利的局面的估价函数值为 +oo,而失败的局面的估价函数值为–oo。
Max
局面:假设这个局面轮到己方走,有多种决策可以选择,其中每种决策都导致一种子局面(sub-state)。由于决策权在我们手中,当然是选择估价函数值 f 最大的子局面,因此该局面的估价函数值等于子局面 f 值的最大值,把这样的局面称为 max 局面。
Min
局面:假设这个局面轮到对方走,它也有多种决策可以选择,其中每种决策都导致一种子局面(sub-state)。但由于决策权在对方手中,在最坏的情况下,对方当然是选择估价函数值 f 最小的子局面,因此该局面的估价函数值等于子局面 f 值的最小值,把这样的局面称为 max 局面。
终结局面:胜负已分(假设没有和局)
假如有如上图的博弈树,设先手为 A ,后手为 B ;则 A 为 max 局面,B 为 min 局面。上图中 A 一开始有 2 种走法( w2 和 w3 ,w表示结点记号),它走 w2 还是 w3 取决于 w2 和 w3 的估价函数值f(),因为 A 是 max 局面,所以它会取 f(w2) 和 f(w3) 中大的那个,f(x) 怎么求呢?通常是以递归的方式对博弈树进行搜索,我们通常可以设定叶子结点局面的估价值。
例如上图的搜索过程为 w1 --> w2 --> w4 ,然后回溯到 w1 --> w2 得到 f(w2) = 3 ,接着 w1 --> w2 --> w5 得到 f'(w2) = 1,因为 w2 在第二层,是 min 局面,所以它会选择得到的结果中小的那个,即用 f'(w2) 替代 f(w2) ,即 f(w2) = 1,[b]接着 w1 -->
w2 --> w6 得到 f'(w2) = 6 > f(w2) ,直接忽略。因此如果 A 往 w2 走的话将会得到一个估价值为 f(w2) = 1 的局面;类似地,如果往 w3 走的话将会得到一个估价值为 f(w3) = -3 的局面。而 A 是 max 局面,所以它会选择估价值大的走法,f(w2) = 1 > f(w3) = -3,因此它下一步走 w2。[/b]
伪代码表示为:
[cpp]
view plain
copy
// player = 1 表示轮到己方, player = 0 表示轮到对方
// cur_node 表示当前局面(结点)
maxmin(player, cur_node)
{
if 达到终结局面
return 该局面结点的估价值 f
end
if player == 1 // 轮到己方走
best = -oo // 己方估价值初始化为 -oo
for 每一种走法 do
new_node = get_next(cur_node) // 遍历当前局面 cur_node 的所有子局面
val = maxmin(player^1, new_node); // 把新产生的局面交给对方,对方返回一个该局面的估价值
if val > best
best = val;
end
end
return best;
else // 轮到对方走
best = +oo // 对方估价值初始化为 +oo
for 每一种走法 do
new_node = get_next(cur_node) // 遍历当前局面 cur_node 的所有子局面
val = maxmin(player^1, new_node); // 把新产生的局面交给对方,对方返回一个该局面的估价值
if val < best
best = val;
end
end
return best;
end
}
[b] 但是,实际问题中的所有局面所产生的博弈树一般都是非常庞大,非常庞大的多叉树~,并不能依靠暴力搜索来寻找最佳解法。因此需要用到一些剪枝手段。常用的比较初级的有 alpha-beta 剪枝。[/b]
[b] 简单地说就是用两个参数 alpha 和 beta 表示当前局面的父局面的估价函数值 f()。如果当前局面为 min 局面,则需要借助父局面目前已求得的 f() (即 alpha)来判断是否需要继续搜索下去;[b]如果当前局面为 max 局面,则需要借助父局面目前已求得的
f() (即 beta)。[/b][/b]
[b][b] 具体来说就是这样,举个例子:[/b][/b]
[b][b] 如果下图是某问题所产生的一颗博弈树,先手 A 为己方,后手 B 为对方。[/b][/b]
[b][b]
[/b][/b]
通过前面所述的方法,如果 A 走 w2 则可以得到这样的结果:
alpha 初始值为 -oo,beta 初始值为 +oo;w1 在得到 f(w1) = 6 的整个过程中, alpha 和 beta 是这样变化的:w1 --> w2 -- > w5 得到 f'(w2) = 6 < f(w2) = +oo,即修改 f(w2) = f'(w2) = 6;同时修改 beta = 6 (因为 w2 的子局面是否需要剪枝依赖于 w2 的估价值 f(),而与 alpha 无关,故不需修改
alpha)。在正常搜索完 w1 --> w2 --> w6 后, w2 层把 beta = 6 返回给上一层 w1 的 alpha,即 w1 层的 alpha = 6,beta = +oo。
接下来在 w3 里搜索就可以体现 alpha-beta 剪枝的效果;A 在选择 w3 走的时候同时把所得的 alpha 和 beta 传递下去,在经过 w1 --> w3 --> w7 得到 f(w3) = 4 (同时使 beta = 4)后,首先进行判断:如果 alpha > beta,则直接返回 beta = 4,没有必要再搜索 w8 和 w9。这是因为这个 alpha 是 w1 在走 w2 这条路时得到的一个估价值
f(w1),而 w3 是 min 局面,它会选择子局面 w7, w8, w9 中 f() 的值小的作为 f(w3),所以 w3 在得到 f(w3) = 4 后如果继续搜索 w8, w9,只会得到更小的值;w1 是 max 局面,它的 f() 要修改的条件是找到估价值比它更大的子局面,[b]而 w1 目前已知的估价值 f(w1) = 6 比 f(w3) 要大,所以无论 w3 再怎么继续搜索下去,w1 都不会选 w3 作为下一步,所以没有必要搜索下去。这样就剪掉了
w8, w9 这两个分支,直接跳出 w3 进入 w4 继续搜索。另外一种情形也是类似的道理,这样就实现了有效的剪枝优化。[/b]
[b] 伪代码表示为:[/b]
[cpp]
view plain
copy
// player = 1 表示轮到己方, player = 0 表示轮到对方
// cur_node 表示当前局面(结点)
maxmin(player, cur_node, alpha, beta)
{
if 达到终结局面
return 该局面结点的估价值 f
end
if player == 1 // 轮到己方走
for 每一种走法 do
new_node = get_next(cur_node) // 遍历当前局面 cur_node 的所有子局面
val = maxmin(player^1, new_node, alpha, beta); // 把新产生的局面交给对方,对方返回一个新局面的估价值
if val > alpha
alpha = val;
end
if alpha > beta
return alpha;
end
end
return alpha;
else // 轮到对方走
for 每一种走法 do
new_node = get_next(cur_node) // 遍历当前局面 cur_node 的所有子局面
val = maxmin(player^1, new_node, alpha, beta); // 把新产生的局面交给对方,对方返回一个新局面的估价值
if val < beta
beta = val;
end
if alpha > beta
return beta;
end
end
return beta;
end
}
机器博弈的核心技术是博弈搜索算法
零和博弈(zero-sum game),又称零和游戏,与非零和博弈相对,是博弈论的一个概念,属非合作博弈。指参与博弈的各方,在严格竞争下,一方的收益必然意味着另一方的损失,博弈各方的收益和损失相加总和永远为“零”,双方不存在合作的可能。
也可以说:自己的幸福是建立在他人的痛苦之上的,二者的大小完全相等,因而双方都想尽一切办法以实现“损人利己”。零和博弈的结果是一方吃掉另一方,一方的所得正是另一方的所失,整个社会的利益并不会因此而增加一分。
----------------------------------------------------------------------------------------------------------------------------------------------------
最单纯的极大极小算法
局面估价函数:我们给每个局面(state)规定一个估价函数值 f,评价它对于己方的有利程度。胜利的局面的估价函数值为 +oo,而失败的局面的估价函数值为–oo。
Max
局面:假设这个局面轮到己方走,有多种决策可以选择,其中每种决策都导致一种子局面(sub-state)。由于决策权在我们手中,当然是选择估价函数值 f 最大的子局面,因此该局面的估价函数值等于子局面 f 值的最大值,把这样的局面称为 max 局面。
Min
局面:假设这个局面轮到对方走,它也有多种决策可以选择,其中每种决策都导致一种子局面(sub-state)。但由于决策权在对方手中,在最坏的情况下,对方当然是选择估价函数值 f 最小的子局面,因此该局面的估价函数值等于子局面 f 值的最小值,把这样的局面称为 max 局面。
终结局面:胜负已分(假设没有和局)
假如有如上图的博弈树,设先手为 A ,后手为 B ;则 A 为 max 局面,B 为 min 局面。上图中 A 一开始有 2 种走法( w2 和 w3 ,w表示结点记号),它走 w2 还是 w3 取决于 w2 和 w3 的估价函数值f(),因为 A 是 max 局面,所以它会取 f(w2) 和 f(w3) 中大的那个,f(x) 怎么求呢?通常是以递归的方式对博弈树进行搜索,我们通常可以设定叶子结点局面的估价值。
例如上图的搜索过程为 w1 --> w2 --> w4 ,然后回溯到 w1 --> w2 得到 f(w2) = 3 ,接着 w1 --> w2 --> w5 得到 f'(w2) = 1,因为 w2 在第二层,是 min 局面,所以它会选择得到的结果中小的那个,即用 f'(w2) 替代 f(w2) ,即 f(w2) = 1,[b]接着 w1 -->
w2 --> w6 得到 f'(w2) = 6 > f(w2) ,直接忽略。因此如果 A 往 w2 走的话将会得到一个估价值为 f(w2) = 1 的局面;类似地,如果往 w3 走的话将会得到一个估价值为 f(w3) = -3 的局面。而 A 是 max 局面,所以它会选择估价值大的走法,f(w2) = 1 > f(w3) = -3,因此它下一步走 w2。[/b]
伪代码表示为:
[cpp]
view plain
copy
// player = 1 表示轮到己方, player = 0 表示轮到对方
// cur_node 表示当前局面(结点)
maxmin(player, cur_node)
{
if 达到终结局面
return 该局面结点的估价值 f
end
if player == 1 // 轮到己方走
best = -oo // 己方估价值初始化为 -oo
for 每一种走法 do
new_node = get_next(cur_node) // 遍历当前局面 cur_node 的所有子局面
val = maxmin(player^1, new_node); // 把新产生的局面交给对方,对方返回一个该局面的估价值
if val > best
best = val;
end
end
return best;
else // 轮到对方走
best = +oo // 对方估价值初始化为 +oo
for 每一种走法 do
new_node = get_next(cur_node) // 遍历当前局面 cur_node 的所有子局面
val = maxmin(player^1, new_node); // 把新产生的局面交给对方,对方返回一个该局面的估价值
if val < best
best = val;
end
end
return best;
end
}
[b] 但是,实际问题中的所有局面所产生的博弈树一般都是非常庞大,非常庞大的多叉树~,并不能依靠暴力搜索来寻找最佳解法。因此需要用到一些剪枝手段。常用的比较初级的有 alpha-beta 剪枝。[/b]
[b] 简单地说就是用两个参数 alpha 和 beta 表示当前局面的父局面的估价函数值 f()。如果当前局面为 min 局面,则需要借助父局面目前已求得的 f() (即 alpha)来判断是否需要继续搜索下去;[b]如果当前局面为 max 局面,则需要借助父局面目前已求得的
f() (即 beta)。[/b][/b]
[b][b] 具体来说就是这样,举个例子:[/b][/b]
[b][b] 如果下图是某问题所产生的一颗博弈树,先手 A 为己方,后手 B 为对方。[/b][/b]
[b][b]
[/b][/b]
通过前面所述的方法,如果 A 走 w2 则可以得到这样的结果:
alpha 初始值为 -oo,beta 初始值为 +oo;w1 在得到 f(w1) = 6 的整个过程中, alpha 和 beta 是这样变化的:w1 --> w2 -- > w5 得到 f'(w2) = 6 < f(w2) = +oo,即修改 f(w2) = f'(w2) = 6;同时修改 beta = 6 (因为 w2 的子局面是否需要剪枝依赖于 w2 的估价值 f(),而与 alpha 无关,故不需修改
alpha)。在正常搜索完 w1 --> w2 --> w6 后, w2 层把 beta = 6 返回给上一层 w1 的 alpha,即 w1 层的 alpha = 6,beta = +oo。
接下来在 w3 里搜索就可以体现 alpha-beta 剪枝的效果;A 在选择 w3 走的时候同时把所得的 alpha 和 beta 传递下去,在经过 w1 --> w3 --> w7 得到 f(w3) = 4 (同时使 beta = 4)后,首先进行判断:如果 alpha > beta,则直接返回 beta = 4,没有必要再搜索 w8 和 w9。这是因为这个 alpha 是 w1 在走 w2 这条路时得到的一个估价值
f(w1),而 w3 是 min 局面,它会选择子局面 w7, w8, w9 中 f() 的值小的作为 f(w3),所以 w3 在得到 f(w3) = 4 后如果继续搜索 w8, w9,只会得到更小的值;w1 是 max 局面,它的 f() 要修改的条件是找到估价值比它更大的子局面,[b]而 w1 目前已知的估价值 f(w1) = 6 比 f(w3) 要大,所以无论 w3 再怎么继续搜索下去,w1 都不会选 w3 作为下一步,所以没有必要搜索下去。这样就剪掉了
w8, w9 这两个分支,直接跳出 w3 进入 w4 继续搜索。另外一种情形也是类似的道理,这样就实现了有效的剪枝优化。[/b]
[b] 伪代码表示为:[/b]
[cpp]
view plain
copy
// player = 1 表示轮到己方, player = 0 表示轮到对方
// cur_node 表示当前局面(结点)
maxmin(player, cur_node, alpha, beta)
{
if 达到终结局面
return 该局面结点的估价值 f
end
if player == 1 // 轮到己方走
for 每一种走法 do
new_node = get_next(cur_node) // 遍历当前局面 cur_node 的所有子局面
val = maxmin(player^1, new_node, alpha, beta); // 把新产生的局面交给对方,对方返回一个新局面的估价值
if val > alpha
alpha = val;
end
if alpha > beta
return alpha;
end
end
return alpha;
else // 轮到对方走
for 每一种走法 do
new_node = get_next(cur_node) // 遍历当前局面 cur_node 的所有子局面
val = maxmin(player^1, new_node, alpha, beta); // 把新产生的局面交给对方,对方返回一个新局面的估价值
if val < beta
beta = val;
end
if alpha > beta
return beta;
end
end
return beta;
end
}
相关文章推荐
- 【五子棋AI】启发算法——主要变例搜索
- 五子棋AI算法第三篇-Alpha Beta剪枝
- 五子棋AI算法第五篇-算杀
- 五子棋AI算法简易实现(六)
- 五子棋AI博弈树之带Alpha-Beta剪枝的极大极小过程函数
- 基于C++实现五子棋AI算法思想
- 【游戏编程】AI-迷宫寻路算法-深度优先搜索和广度优先搜索
- 五子棋AI算法简易实现(三)
- 五子棋AI算法第七篇-Zobrist
- 五子棋AI算法第四篇-启发式搜索函数
- cocos 2dx 基于C++的 五子棋AI算法思想
- 五子棋AI算法第六篇-迭代加深
- AS3.0五子棋判断胜负及人机算法(AI)
- 关于五子棋电脑AI算法的一些思考
- 五子棋AI算法简易实现(七)
- 【五子棋AI】启发算法——迭代加深与内部迭代加深
- 【五子棋AI】启发算法——置换表
- [算法] 极大极小搜索
- 【五子棋AI】启发算法——VCF/VCT搜索
- AI-迷宫寻路算法-深度优先搜索和广度优先搜索