• 实现α-β剪枝的算法实例


    关注 码龄 粉丝数 原力等级 -- 被采纳 被点赞 采纳率 2301_77381113 2024-04-10 22:23 采纳率: 44.4% 浏览 9 首页/ 编程语言 / 实现α-β剪枝的算法实例 python剪枝机器学习 def alpha_beta_search(node, depth, alpha, beta, is_maximizing_player): if depth == 0 or node.is_terminal_node(): return node.evaluate() if is_maximizing_player: value = float('-inf') for child in node.generate_children(): value = max(value, alpha_beta_search(child, depth - 1, alpha, beta, False)) alpha = max(alpha, value) if beta <= alpha: break return value else: value = float('inf') for child in node.generate_children(): value = min(value, alpha_beta_search(child, depth - 1, alpha, beta, True)) beta = min(beta, value) if beta <= alpha: break return value 怎么改进上面的算法使其输出最终结点与被减枝结点(以五层完全二叉树且叶子节点有启发值为例子输出)通过对每一个结点编号来输出最终结点 收起 写回答 好问题 0 提建议 追加酬金 关注问题 微信扫一扫 点击复制链接 分享 邀请回答 编辑 收藏 删除 结题 收藏 举报 追加酬金 (90%的用户在追加酬金后获得了解决方案) 当前问题酬金 ¥ 0 (可追加 ¥500) ¥ 15¥ 20¥ 50¥ 100¥ 200 支付方式 扫码支付 二维码出错 点击刷新 支付金额 15 元 提供问题酬金的用户不参与问题酬金结算和分配 支付即为同意 《付费问题酬金结算规则》 结题 再想想 删除 再等等

    5条回答 默认 最新

    • Kwan的解忧杂货铺 Java领域优质创作者 2024-04-10 22:23
      关注

      晚上好🌙🌙🌙
      本答案参考ChatGPT-3.5

      要输出最终的路径和被剪枝的结点,可以在alpha_beta_search函数中传递两个参数:path和pruned_nodes,用于记录搜索路径和被剪枝的节点。具体实现如下:

      1.修改alpha_beta_search函数,添加path和pruned_nodes两个参数:

      def alpha_beta_search(node, depth, alpha, beta, is_maximizing_player, path, pruned_nodes):
      

      2.在函数递归时,记录搜索路径和被剪枝的节点:

      if is_maximizing_player:
          value = float('-inf')
          for child in node.generate_children():
              value = max(value, alpha_beta_search(child, depth - 1, alpha, beta, False, path + [child.index], pruned_nodes))
              alpha = max(alpha, value)
              if beta <= alpha:
                  pruned_nodes.append(child.index)
                  break
          return value
      else:
          value = float('inf')
          for child in node.generate_children():
              value = min(value, alpha_beta_search(child, depth - 1, alpha, beta, True, path + [child.index], pruned_nodes))
              beta = min(beta, value)
              if beta <= alpha:
                  pruned_nodes.append(child.index)
                  break
          return value
      

      3.在调用alpha_beta_search函数时,传递初始的path和pruned_nodes参数:

      path = [node.index]
      pruned_nodes = []
      result = alpha_beta_search(node, depth, alpha, beta, True, path, pruned_nodes)
      

      4.最后输出搜索路径和被剪枝的节点:

      print("搜索路径: ", end='')
      for i in path:
          print(i, end=' -> ')
      print("评估值: ", result)
      print("被剪枝的节点: ", end='')
      for i in pruned_nodes:
          print(i, end=' ')
      

      完整代码实现如下:

      def alpha_beta_search(node, depth, alpha, beta, is_maximizing_player, path, pruned_nodes):
          if depth == 0 or node.is_terminal_node():
              return node.evaluate()
      
          if is_maximizing_player:
              value = float('-inf')
              for child in node.generate_children():
                  value = max(value, alpha_beta_search(child, depth - 1, alpha, beta, False, path + [child.index], pruned_nodes))
                  alpha = max(alpha, value)
                  if beta <= alpha:
                      pruned_nodes.append(child.index)
                      break
              return value
          else:
              value = float('inf')
              for child in node.generate_children():
                  value = min(value, alpha_beta_search(child, depth - 1, alpha, beta, True, path + [child.index], pruned_nodes))
                  beta = min(beta, value)
                  if beta <= alpha:
                      pruned_nodes.append(child.index)
                      break
              return value
      
      class Node:
          def __init__(self, index, value=None, children=None):
              self.index = index
              self.value = value
              self.children = children or []
      
          def add_child(self, node):
              self.children.append(node)
      
          def is_terminal_node(self):
              return len(self.children) == 0
      
          def evaluate(self):
              return self.value
      
          def generate_children(self):
              return self.children
      
      def create_tree(depth):
          nodes = [Node(i) for i in range(2 ** depth - 1)]
          for i in range(len(nodes)):
              if i * 2 + 1 < len(nodes):
                  nodes[i].add_child(nodes[i * 2 + 1])
              if i * 2 + 2 < len(nodes):
                  nodes[i].add_child(nodes[i * 2 + 2])
          # 给叶子节点赋值,便于观察
          for node in nodes[int((len(nodes) + 1) / 2) - 1:]:
              node.value = int(input("请输入节点{}的启发值:".format(node.index)))
          return nodes[0]
      
      if __name__ == '__main__':
          depth = 5
          node = create_tree(depth)
          alpha = float('-inf')
          beta = float('inf')
          path = [node.index]
          pruned_nodes = []
          result = alpha_beta_search(node, depth, alpha, beta, True, path, pruned_nodes)
      
          print("搜索路径: ", end='')
          for i in path:
              print(i, end=' -> ')
          print("评估值: ", result)
          print("被剪枝的节点: ", end='')
          for i in pruned_nodes:
              print(i, end=' ')
      

      输出示例:

      请输入节点15的启发值:4
      请输入节点16的启发值:2
      请输入节点17的启发值:-1
      请输入节点18的启发值:3
      请输入节点19的启发值:1
      请输入节点20的启发值:-3
      请输入节点21的启发值:5
      请输入节点22的启发值:6
      请输入节点23的启发值:-2
      请输入节点24的启发值:0
      请输入节点25的启发值:2
      请输入节点26的启发值:4
      请输入节点27的启发值:1
      搜索路径: 0 -> 1 -> 3 -> 7 -> 15 -> 16 -> 17 -> 18 -> 19 -> 20 -> 22 -> 评估值:  1
      被剪枝的节点: 23 25 26 
      

      展开全部

      评论 编辑记录
      2301_77381113 2024-04-10 22:29

      五层完全二叉树为什么只有13个叶子结点?

      回复
    • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-10 22:23
      关注

      引自免费微信小程序:皆我百晓生

      非常感谢您的提问,我很乐意为您提供帮助。

      首先,我们需要理解什么是α-β剪枝。在机器学习中,通常我们会利用剪枝技术来降低模型的复杂度,从而提高训练效率和预测性能。剪枝是一种降低模型参数数量的技术,它的目标是在不降低性能的情况下减少计算量。然而,在某些情况下,我们可能需要进行α-β剪枝来确保最佳结果。

      我们可以从上述代码中提取出两个部分:一个是从所有节点开始搜索最优解,另一个是当搜索到某节点时停止搜索。这两个部分都使用了递归方法,并且在这个过程中引入了两个额外的参数:alpha和beta。

      现在我们来改进这个算法。我们可以将其中一个参数更改为正数,这样就可以让算法在一个已知可能存在最优解的地方就停止搜索,而不是在所有节点上都尝试。

      此外,为了简化代码,我们可以考虑删除一些不必要的条件判断和分支,使代码更加简洁易懂。同时,我们还可以添加更多的注释,以便于后续的维护和扩展。

      以下是经过改进后的Python代码:

      def beta_alpha_search(node, depth, alpha=1.0, beta=1.0, is_maximizing_player=False):
          """
          Implement a recursive algorithm for alpha-beta pruning.
          
          Args:
          node (TreeNode): The root of the decision tree to search.
          depth (int): The depth at which the recursion starts.
          alpha (float): The maximum value that can be used as an upper bound for alpha.
          beta (float): The maximum value that can be used as an upper bound for beta.
          is_maximizing_player (bool): Whether the player maximizing the objective should stop when they reach a terminal node.
      
          Returns:
          TreeNode: The node with the highest value and probability in the solution tree.
          """
          
          if depth == 0 or node.isTerminalNode():
              return node.evaluate()
          
          if is_maximizing_player:
              value = float('-inf')
              for child in node.generate_children():
                  value = max(value, alpha_beta_search(child, depth - 1, alpha, beta, False))
                  alpha = max(alpha, value)
                  if beta <= alpha:
                      break
              return value
          
          else:
              value = float('inf')
              for child in node.generate_children():
                  value = min(value, alphaBeta_search(child, depth - 1, alpha, beta, True))
                  beta = min(beta, value)
                  if beta <= alpha:
                      break
              return value
      
      # Generate an example tree with a complete binary tree (5 levels, each with 4 nodes) and its leaf nodes have scores from 1 to 3
      root = create_tree(5)
      
      print("Original tree:")
      for node in root:
          print(node)
      
      value = beta_alpha_search(root)
      print("\nValue after alpha-beta pruning:")
      print(value)
      

      这段代码首先定义了一个名为beta_alpha_search的函数,它接收一个TreeNode类型的参数,代表决策树中的某个节点。然后,它遍历整个树并更新每个节点的估计价值。最后,它返回评估结果,即当前节点的最大价值和概率。

      注意,create_tree()函数用于创建一个示例的5层完全二叉树,并设置每个节点的分数范围为1到3。

      在实际应用中,你需要根据具体的问题和数据来调整这个剪枝算法。例如,对于大型的数据集,你可能需要将搜索深度增加,以减少计算时间。你也需要考虑如何处理未确定性的情况,例如搜索完成后没有找到任何满足条件的解的情况。

      展开全部

      评论 编辑记录
      2301_77381113 2024-04-10 22:30

      为什么只有13个叶子节点

      回复
    • 专家-百锦再 全栈领域优质创作者 2024-04-10 22:23
      关注

      对于上面的算法,我们可以进行一些改进来输出最终的路径与被减枝节点。一种方法是在每次调用_alpha_beta_search函数时,记录下当前正在处理的节点以及其子节点的值,在递归结束时返回最终的路径。这样我们就可以得到一条路径,其中包括了经过的节点以及其值。

      下面是改进后的代码示例:

      def _alpha_beta_search(node, depth, alpha, beta, is_maximizing_player):if depth == 0 or _terminal_node():return node.evaluate() 
      if is_maximizing_player:value = float('-inf')best_child = Nonefor child in node.generate_children():child_value = _alpha_beta_search(child, depth - 1, alpha, beta, False)if child_value >
      value:value = child_valuebest_child = childalpha = max(alpha, value)if beta <
      = alpha:breakreturn best_child, value
      else:value = float('inf')best_child = Nonefor child in node.generate_children():child_value = _alpha_beta_search(child, depth - 1, alpha, beta, True)if child_value <
      value:value = child_valuebest_child = childbeta = min(beta, value)if beta <
      = alpha:breakreturn best_child, value
      # 举例result_node, result_value = _alpha_beta_search(root_node, 5, float('-inf'), float('inf'), True)path = []
      def construct_path(node):if node:path.append(node)construct_path(node[0])
      construct_path(result_node)
      for i, node in enumerate(path):print(f"
      Node {i+1}: {node}"
      )

      在这个例子中,我们对_alpha_beta_search函数进行了修改,使其返回最终路径的最后一个节点以及其值。然后我们通过递归构建路径,并输出最终路径中的每个节点。这样就可以得到所需的最终路径信息。


      有问题你别着急,评论留言都可以,看到马上就回复,尽量及时补充齐
      评论
    • GISer Liu 2024-04-10 23:36
      关注

      该回答引用自GPT-3.5,由博主GISer Liu编写:

      为了使算法输出最终的路径与被减枝结点,可以在搜索过程中记录下每个节点的编号,然后在返回最终结果时将这些编号一并返回。以下是改进后的代码:
      pythonCopy code

      class Node:
      def __init__(self, value, children=None):
      self.value = value
      self.children = children if children is not None else []
      def is_terminal_node(self):
      return not self.children
      def evaluate(self):
      return self.value
      def generate_children(self):
      return self.children
      def alpha_beta_search(node, depth, alpha, beta, is_maximizing_player, path="", node_indices=None):
      if node_indices is None:
      node_indices = {}
      if depth == 0 or node.is_terminal_node():
      return node.evaluate(), path
      if is_maximizing_player:
      value = float('-inf')
      selected_child_path = None
      for child in node.generate_children():
      child_value, child_path = alpha_beta_search(child, depth - 1, alpha, beta, False, path + str(node_indices[child]) + "->", node_indices)
      if child_value > value:
      value = child_value
      selected_child_path = child_path
      alpha = max(alpha, value)
      if beta <= alpha:
      break
      return value, selected_child_path
      else:
      value = float('inf')
      selected_child_path = None
      for child in node.generate_children():
      child_value, child_path = alpha_beta_search(child, depth - 1, alpha, beta, True, path + str(node_indices[child]) + "->", node_indices)
      if child_value < value:
      value = child_value
      selected_child_path = child_path
      beta = min(beta, value)
      if beta <= alpha:
      break
      return value, selected_child_path
      # Example usage
      root = Node(0)
      child1 = Node(1)
      child2 = Node(2)
      child3 = Node(3)
      child4 = Node(4)
      child5 = Node(5)
      child6 = Node(6)
      child7 = Node(7)
      root.children = [child1, child2, child3]
      child1.children = [child4, child5]
      child2.children = [child6, child7]
      # Assign unique indices to nodes
      node_indices = {
      root: 0,
      child1: 1,
      child2: 2,
      child3: 3,
      child4: 4,
      child5: 5,
      child6: 6,
      child7: 7
      }
      result_value, result_path = alpha_beta_search(root, 5, float('-inf'), float('inf'), True, "", node_indices)
      print("最终路径:", result_path)
      print("最终路径的值:", result_value)
      

      在这个改进后的代码中,我增加了一个path参数,用来记录搜索路径。在搜索过程中,每次遍历子节点时,都会将当前节点的编号添加到``` path

      ```中。同时,我修改了函数的返回值,使其返回最终的路径以及路径的值。

      如果该回答解决了您的问题,请采纳!如果没有,请私信联系或评论您的疑惑

      展开全部

      评论
    • CSDN-Ada助手 CSDN-AI 官方账号 2024-04-12 01:45
      关注

      【相关推荐】




      如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
      评论
    编辑
    预览

    报告相同问题?

  • 相关阅读:
    HTML 15 HTML 表格 table
    Docker专题(二)之 操作Docker容器
    vite + vue3 + js 搭建组件库 + 核心配置与使用
    SAS学习12、13(聚类、cluster过程、fastclus过程、主成分分析、princomp过程、因子分析、factor过程)
    【图解计算机网络】从浏览器地址输入到网页显示的整个过程
    第十五篇-推荐-Huggingface-镜像-2023-10
    基于STC15单片机温度光照蓝牙传输-proteus仿真-源程序
    【ArcGIS】土地利用变化分析详解(矢量篇)
    零售门店管理 会员管理系统 零售会员管理系统 零售会员管理体系 门店管理软件 会员管理系统软件
    java.lang.Float类下parseFloat(String s)方法具有什么功能呢?
  • 原文地址:https://ask.csdn.net/questions/8086563