经典的C++ Alpha–beta剪枝代码是否适用于非二叉树(每个节点有3个或更多子节点)?因为所有这些代码的示例都使用的是二叉树,当我在VS中运行这段代码时,实际答案(在纸上计算的)和代码的结果不同。这是否正常?这是从网上找到的代码:
#include <iostream>#include <algorithm>#include <cmath>#include <climits>#define SIZE(arr) (sizeof(arr) / sizeof(arr[0]))using namespace std;int getHeight(int n) { return (n == 1) ? 0 : 1 + log2(n / 2);}int minmax(int height, int depth, int nodeIndex,bool maxPayer, int values[], int alpha,int beta) { if (depth == height) { return values[nodeIndex]; } if (maxPayer) { int bestValue = INT_MIN; for (int i = 0; i < height - 1; i++) { //MAYBE THE PROBLEM IS HERE?????? int val = minmax(height, depth + 1, nodeIndex * 2 + i, false, values, alpha, beta); bestValue = max(bestValue, val); alpha = max(alpha, bestValue); if (beta <= alpha) break; } return bestValue; } else { int bestValue = INT_MAX; for (int i = 0; i < height - 1; i++) { int val = minmax(height, depth + 1, nodeIndex * 2 + i, true, values, alpha, beta); bestValue = min(bestValue, val); beta = min(beta, bestValue); if (beta <= alpha) break; } return bestValue; }}int main() { int values[] ={9,3,10,20,1,15,2,27,35,4,7,14,2,1,55,0,8,6,0,2,80,47,33,42,14,25,1 }; ////for example, 9,3 and 10 are the children of the same node int height = getHeight(SIZE(values)); int result = minmax(height, 0, 0, true, values, INT_MIN, INT_MAX); cout <<"Result : " << result << "\n"; return 0;}
回答:
看起来您是用堆结构定义了一个树。
如果节点的子节点数量是可变的(“3个或更多”),您不能真正使用这种数组结构来表示树。这适用于完整的树:
- 每个节点要么有k个子节点,要么没有子节点,但有一个节点例外,它可以有1到k个子节点(这些是叶子节点)。
- 树的所有层级都完全填充
- 除了最后一层可能不完整,但该层的所有叶子节点都应在该层的最左侧。这一层底部的右侧叶子节点是第一条规则中提到的例外节点的子节点。
所以,如果您的树遵循这些规则,那么您仍然需要对代码进行一些调整,因为它仍然是指k为2的情况(二叉树)。
从您的代码中的注释来看,您没有为树的根存储值(因为您称9为子节点),因此索引0处的值是根的子节点,而不是根本身。
- 计算树高度的公式为:1 + ⌊logk(n+1)⌋。在n上加1是为了考虑缺少的根值。
- 节点的子节点数量不依赖于高度,而是依赖于k(您应该定义它,可能作为常量)。所以您的
for
循环应该运行k次。 - 子节点的索引不是
nodeIndex * 2 + i
,而是nodeIndex * k + i