【问题标题】:Alpha–beta pruning in non-binary-tree非二叉树中的 Alpha-beta 修剪
【发布时间】:2021-07-08 23:11:17
【问题描述】:

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;
}

【问题讨论】:

  • 听起来你可能需要学习如何使用调试器来单步调试你的代码。使用好的调试器,您可以逐行执行您的程序,并查看它与您期望的偏差在哪里。如果您要进行任何编程,这是必不可少的工具。进一步阅读:How to debug small programsDebugging Guide
  • @NathanOliver 我正在使用带有 F11 的 VS 调试器(逐步),但它没有帮助。
  • 这个问题与您之前删除的基本相同的question 有何不同?
  • 发布相同的问题无助于获得好的答案,但会提高其质量。
  • @Evg 是的,确实如此,问题是没有好的或坏的答案,根本没有答案。我可以接受。

标签: c++ algorithm tree artificial-intelligence binary-search-tree


【解决方案1】:

看起来您在堆结构中定义了一棵树。

如果节点的子节点数量是可变的(“3 或更多”),则不能真正使用此数组结构来表示树。它适用于完整的树:

  • 每个节点要么有 k 个子节点,要么没有子节点,但一个节点除外,它可以有 1 到 k 之间的任意数量的子节点(即叶子)。
  • 树的所有级别都已完全填充
  • 除了可能不完整的最后一层,但该层中的所有叶节点都应位于该层的左侧。此底层最右边的叶子是第一个要点中提到的异常节点的子节点。

因此,如果您的树遵循这些规则,那么您仍然需要对您的代码进行一些调整,因为它仍然指的是 k 为 2(二叉树)的情况。

从代码中的注释来看,您似乎没有为树的根存储值(因为您将 9 称为子项),因此索引 0 处的值是一个 子项 根,而不是根本身。

  • 知道树高的公式是:1 + logk(n+ 1)n 加 1 是为了说明缺少的根值。
  • 节点的子节点数量不取决于高度,而是取决于 k(您应该定义它,可能是一个常数)。所以你的 for 循环应该运行 k 次。
  • 孩子的索引不是nodeIndex * 2 + i,而是nodeIndex * k + i

【讨论】:

  • 谢谢。我将使用您的答案修改我的代码
猜你喜欢
  • 1970-01-01
  • 2021-01-25
  • 2021-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多