机器博弈———α-β 算法原理

首先明了极大极小搜索https://baike.baidu.com/item/%E6%9E%81%E5%A4%A7%E6%9E%81%E5%B0%8F%E5%80%BC%E7%AE%97%E6%B3%95/19473878

在极大极小搜索的过程中,存在着2 种明显的冗余现象:

极大值冗余

第1 种现象是极大值冗余。在上图中,节点A 的值应是节点 B 和节点C 的值中之较大者。现在已知节点 B 的值大于节点D 的值。由于节点C 的值应是它的诸子节点的值中之极小者,此极小值一定小于等于节点D 的值,因此亦一定小于节点B 的值,这表明,继续搜索节点C 的其他诸子节点E ,F ...已没有意义,它们不能做任何贡献,于是把以节点 C 为根的子树全部剪去。这种优化称为Alpha 剪枝。

极小值冗余

第二种是与极大值冗余对偶的现象,称为极小值冗余。节点A 的值应是节点B 和节点C 的值中之较小者。 现在已知节点B 的值小于节点D 的值。 由于节点C 的值应是它的诸子节点的值中之极大者,此极大值一定大于等于节点 D 的值,因此也大于节点B的值,这表明,继续搜索节点C 的其他诸子节点已没有意义,并可以把以节点C 为根的子树全部剪去,这种优化称为Beta剪枝。

把Alpha -Beta 剪枝应用到极大极小算法中,就形成了Alpha -Beta搜索算法。

下面给一个例子,非常清晰

 

先做个说明:有画弧线的是与,取较小值,没有的是或,去最大值。

第一步:2、9、3做比较,取最小值2,I点确定为2

第二步:J点的1和I点2大小进行比较,如果1是J点的最小值,由于J的父节点是取较大值,1<2,无法升高D的值,所以J点的-1可以点可停止搜索,我们划掉该值。

第三步:I点2接着与K点的左值-1进行比较,如果-1是最小值,由于K的父节点取较大值,-1<2,无法升高D的取值,所以K点的右值可以停止搜索。

第四步:D的值可以确定为2

第五步:L点的作用值进行比较,取较小值6,D值与L值相比较,由于E去较大值,假设L就是最大值,E=6,二B点取得是D和E的较小值,2<6,E的结果值无法降低B的取值,所以E的右枝可以截掉。

第六步:B的值可以确定为2

第七步:N的左右值进行比较,取0,N点在和O点的左值-5进行比较,假设-5是最小值,0>-5,O点的取值无法升高父节点F的值,所以可以停止搜索O点的右枝。

第八步:F确定为0.

第九步:F点假设是C的最小值,它和B点的值比较,2>0,也就是说C点的取值无法升高A点的取值,所以G和H都停止搜索。

第十步:A点取2,结束

本文章转自https://www.cnblogs.com/tk55/articles/6012314.html

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的六子棋博弈树α-β剪枝算法的代码示例,仅供参考: ``` const int MAXN = 8; const int INF = 0x3f3f3f3f; int board[MAXN][MAXN]; int ai, human; // ai 表示 AI 方,human 表示玩家方 int dx[8] = {1, 1, 0, -1, -1, -1, 0, 1}; int dy[8] = {0, 1, 1, 1, 0, -1, -1, -1}; bool valid(int x, int y) { // 判断坐标是否越界 return x >= 0 && x < MAXN && y >= 0 && y < MAXN; } int evaluate(int color) { // 评估函数,计算当前局面得分 int score = 0; for (int i = 0; i < MAXN; i++) { for (int j = 0; j < MAXN; j++) { if (board[i][j] == color) { for (int k = 0; k < 8; k++) { int cnt = 0, empty = 0, blocked = 0; for (int t = 1; t <= 5; t++) { int x = i + t * dx[k], y = j + t * dy[k]; if (valid(x, y)) { if (board[x][y] == color) cnt++; else if (board[x][y] == 0) empty++, blocked++; else blocked++; } else { blocked++; } } if (cnt == 4 && empty == 1) score += 10000; else if (cnt == 3 && empty == 2) score += 1000; else if (cnt == 2 && empty == 3) score += 100; else if (cnt == 1 && empty == 4) score += 10; else if (cnt == 0 && empty == 5) score += 1; } } } } return score; } int alphabeta(int depth, int alpha, int beta, bool maximize) { // α-β剪枝算法 if (depth == 0) return evaluate(ai); // 到达搜索深度限制,返回当前局面得分 int score = maximize ? -INF : INF; for (int i = 0; i < MAXN; i++) { for (int j = 0; j < MAXN; j++) { if (board[i][j] == 0) { board[i][j] = maximize ? ai : human; if (maximize) { // MAX 节点 score = max(score, alphabeta(depth - 1, alpha, beta, false)); alpha = max(alpha, score); } else { // MIN 节点 score = min(score, alphabeta(depth - 1, alpha, beta, true)); beta = min(beta, score); } board[i][j] = 0; // 回溯 if (alpha >= beta) return score; // 剪枝 } } } return score; } int main() { // 初始化棋盘和玩家方 memset(board, 0, sizeof(board)); ai = 1, human = 2; // AI 先手下一步 int x, y; alphabeta(6, -INF, INF, true); // 找到得分最高的位置 int maxscore = -INF; for (int i = 0; i < MAXN; i++) { for (int j = 0; j < MAXN; j++) { if (board[i][j] == 0 && evaluate(ai) > maxscore) { maxscore = evaluate(ai); x = i, y = j; } } } board[x][y] = ai; // 玩家下棋,略 return 0; } ``` 需要注意的是,该代码仅实现了六子棋博弈树α-β剪枝算法的核心部分,还需要根据具体情况进行适当的修改和完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值