1

我目前正在尝试从目标状态进行回归搜索,以找出将为我的 GOAP 规划器实现目标状态的操作列表。到目前为止,我所记录的伪代码如下所示:

closedList = list;
s = stack;
s.push(goal);
while(s.size() > 0)
{
    state = s.pop;
    if(!state exists in closedList)
    {
        closedList.add(state);
        for(action = firstAction; action != lastAction; action = nextAction)
        {
            if(action.getEffect() == state)
            {
                if(!action.ConditionsFulfilled())
                {
                    conditionList = action.getConditions;
                    for(i = 0; i < conditionList.size(); i++)
                    {
                        s.push(conditionList[i]);
                    }
                }
            }
        }
    }
}

我听说 GOAP 与 A* 算法完全一样,只是节点是状态,边是动作。但是由于在 A* 中,节点不需要满足任何条件,这让我很困惑如何调整 A* 算法以处理先决条件。我正在努力理解的是如何存储动作并比较动作的成本以找到最有效的路径。如果我们假设类动作有一个函数 getCost() 返回动作的成本,那么在考虑先决条件时我将如何处理?

4

1 回答 1

2

节点确实是 WorldStates。边缘是行动。但请注意,它们是有向边!

前置条件的来源:它们确定哪些边(动作)流出节点。只有满足其先决条件的动作才是退出该状态节点的有效边。

因此,为了查找节点的邻居,您将检查每个操作是否满足所有先决条件。如果是这样,应用后置条件来查看操作将导致的节点。然后,该动作是这些状态(节点)之间的有效边。

请参阅开源的GPGOAP(面向通用目标的行动计划),了解具有 A* 的 GOAP 实施。这是解释所有步骤的简单 C 代码。我是GPGOAP的作者。

回归的思考

现在是回归部分:我从来没有实现从目标到当前世界状态的向后搜索。所以我在这方面的帮助是有限的。

两个相邻节点仍将基于一个动作连接。您现在启用/禁用边缘不是基于动作的前置条件,而是动作的后置条件。如果后置条件与当前节点不匹配,则该操作将无效。如果是这样,我希望您通过强制执行操作的前提条件来添加邻居。

您喜欢向后搜索而不是向前搜索的原因是什么?

于 2017-11-10T03:32:38.100 回答