我目前正在尝试从目标状态进行回归搜索,以找出将实现我的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()来返回操作的代价,那么在考虑前置条件时我该怎么做呢?
答案 0 :(得分:1)
节点确实是世界状态。 而边缘是行动。但请注意,它们是指向边缘的!
前提条件的来源: 它们确定哪些边(动作)流出节点。 只有满足其前置条件的操作才是退出该状态节点的有效边。
因此,为了找到节点的邻居,如果满足所有前提条件,则应检查每个动作。如果是,请应用后置条件以查看操作将导致的节点。然后,该操作是这些状态(节点)之间的有效边缘。
请参阅开源GPGOAP(通用目标导向行动计划),以实施带有A *的GOAP。 C语言中的简单代码解释了所有步骤。我是GPGOAP的作者。
关于回归的想法
现在是回归部分:我从来没有实现从目标到当前世界状态的向后搜索。所以我可以在这方面提供有限的帮助。
仍将基于单个动作连接两个相邻节点。您现在启用/禁用边缘不是基于操作的前提条件,而是基于操作的后置条件。如果post条件与当前节点不匹配,则该操作将无效。如果是这样,我希望您通过强制执行操作的前提条件来添加邻居。
您更倾向于向前搜索而不是向前搜索?