当前位置: 首页 > 知识库问答 >
问题:

Transposition Tables如何与Hypermax一起工作?

赵志
2023-03-14

我想知道是否有人可以帮助我理解如何将转换表合并到Hypermax算法中。任何示例、伪代码、技巧或实现参考都将不胜感激!

一点背景:

  • Hypermax是一种递归游戏树搜索算法,用于n人游戏,通常用于3人游戏。它是最小最大和α-β修剪的扩展
  • 通常,在游戏树中的每个节点,当前玩家(选择者)将查看其可以做出的所有移动,并选择一个最大化其自身效用的移动。不同于最小值/最大值
  • 我理解换位表是如何工作的,但我不知道当找到换位表条目时,存储在其中的值将如何用于启动截断。带换位的minimax中需要换位标志

Javascript 中没有换位表的超大算法:

/**
 * @param {*} state A game state object.
 * @param {number[]} alphaVector The alpha vector.
 * @returns {number[]} An array of utility values for each player.
 */
function hypermax(state, alphaVector) {
    // If terminal return the utilities for all of the players
    if (state.isTerminal()) {
        return state.calculateUtilities();
    }

    // Play out each move
    var moves = state.getLegalMoves();
    var bestUtilityVector = null;
    for (var i = 0; i < moves.length; ++i) {
        var move = moves[i];
        state.doMove(move);     // move to child state - updates game board and advances player 1
        var utilityVector = hypermax(state, alphaVector.slice(0));  // copy the alpha values down
        state.undoMove(move);   // return to this state - remove board updates and rollsback player 1

        // Select this as best utility if first found
        if (i === 0) {
            bestUtilityVector = utilityVector;
        }

        // Update alpha
        if (utilityVector[state.currentPlayer] > alpha[state.currentPlayer]) {
            alpha[state.currentPlayer] = utilities[state.currentPlayer];
            bestUtilities = utilityVector;
        }

        // Alpha prune
        var sum = 0;
        for (var j = 0; j < alphaVector.length; ++j) {
            sum += alpha[j];
        }
        if (sum >= 0) {
            break;
        }
    }
}

引用:

  • 不带换位表的Hypermax实现:https://meatfighter.com/spotai/#references_2
  • 带α-β修剪和换位表的Minimax(negamax变量):https://en.wikipedia.org/wiki/Negamax#Negamax_with_alpha_beta_pruning_and_transposition_tables
  • Hypermax的原始推导和证明:http://uu.diva-portal.org/smash/get/diva2:761634/FULLTEXT01.pdf

共有1个答案

龙飞
2023-03-14

这个问题相当宽泛,所以这是一个同样宽泛的答案——如果有具体的东西,请澄清你不明白的地方。

在多人游戏中,不能保证转置表是正确的,但是如果你小心地实现它们,它们是正确的。本文对此进行了简要讨论:

多人游戏、算法和方法

总之,关于多玩家游戏树中的换位表,有三点需要注意。首先,他们要求我们与节点排序保持一致。第二,由于换位需要更多的动作,所以它们可能比两人游戏中的效果差。最后,投机修剪可以从换位表中受益,因为它们可以抵消重新搜索游戏树部分的成本。

除了排序问题之外,您可能需要在分支下方存储搜索深度、下一个要玩的玩家,以及用于修剪子树的边界。例如,如果您在第一次搜索中修剪树的边界不同,则在第二次搜索中可能不会产生正确的结果。

HyperMax只是Max^n的一个轻微变体,带有推测性修剪,因此您可能希望查看该上下文,看看是否可以在Max^n中实现某些内容。

 类似资料:
  • 问题内容: 继续我提出的问题,我试图在我的代码库中使用ThreadPoolExecutor。即使反复尝试从Java API文档中理解,我也无法清楚地理解keepAliveTime要在构造函数中传递的参数的功能/目的。希望有人可以通过一些很好的例子向我解释。 Java文档摘录: keepAliveTime-当线程数大于内核数时,这是多余的空闲线程将在终止之前等待新任务的最长时间。 问题答案: 假设您

  • 我已经在Angular 2上使用ImmutableJS有一段时间了,因为它在变化检测方面的性能优势。看这里。 然而,我不太清楚,为什么Immutable在默认情况下与Angular 2一起工作。当没有显式数组时,它如何知道如何迭代值并显示它们?它是否每次访问集合的值时都调用?它实现了Angular 2自动调用的某种方法吗? 如果是这样的话,有没有一种方法可以定义您自己的集合来实现这个方法? 例如:

  • 我试图在一个我的组件中使用Tesseract来执行文件上的ocr。 .ts: .html 我遵循了这个,但是这个错误显示了 我应该怎么做才能让这个工作成功?

  • 我只是很难让我的控制器单元测试正常工作,因为在我看来,如果使用OAuth,SpringDoc中的内容是不够的。在我的例子中,是Oauth2和JWT。 我尝试使用,,甚至使用和自定义定义我自己的注释,但在计算安全表达式时,总是在UserSecurityContext中获得匿名用户,无论我在工厂中设置测试上下文的是什么。。。 我提出了我刚刚想到的解决方案,但由于我不确定嘲笑令牌服务是最有效/干净的方法

  • 我的pom。xml如下所示 我已经尝试了三天,使用REdhat入门指南让这个简单的示例代码与Infinispan一起使用,并下载了快速入门zip来运行它,但仍然不起作用!我一直收到Spring JMS的错误“无法连接到foo: 11222”或“池未打开”,然后是关于混合Uber和Jars版本的警告。我开始使用ehcache,这很难实现,因为只有有限的简单示例展示了如何从rest调用等中存储、检索和

  • 我正在尝试用库制作一个程序。 当我尝试访问一个头函数时,我得到了一个错误。 main.cpp: 测试h: 我是初学者,所以我真的不知道如何修复它或它的可能性。