我正在尝试实现A *算法,以解决以下问题:
问题出在5 /点。
的确,当从当前状态寻找可能的子状态时,我不能每次都创建一个全新的状态,因为这样做的成本太高了(在内存和速度方面)。结果,我正在处理一个状态,当将操作应用于前一个状态时,该状态会发生突变以反映结果状态。 (我可以回滚一个动作)。我正在考虑通过以下方式实现A *:
//_state; //represent the "singleton" states that I can apply and rollback actions instead of cloning it
while (openNodes.Any())
{
var currentNode = openNodes.DeQueue();
currentNode.AdvanceFromStart(_state); //make _state such as all action on the path from the root to currentNode are played
if (IsFinal(_state))
return;
AddToVisitedStates(_state);
foreach(var transition in currentNode.GetPossibleActions())
{
var childNode = new Node(initialState:_state,action:transition.Action);
//here _state is still reflecting the situation from the currentNode point of view
childNode.ApplyAction(_state);
//now _state reflect the situation from childNode point of view
if (WasVisited(_state))
{
childNode.RollbackAction(_state);
continue;
}
if (childNode.CostToReachNode == 0 ||
currentNode.CostToReachNode + transition.Cost < childNode.CostToReachNode)
{
childNode.CostToReachNode = node.CostToReachNode + transition.CostToReachNode;
childNode.CostToReachFinal = childNode.CostToReachNode + HeuristicToReachFinalFromState(_state);
openNodes.ReOrder(childNode);
}
if (!openNodes.Contains(childNode))
openNodes.Add(childNode);
childNode.RollbackAction(_state);
}
currentNode.RollbackToInitialState(_state);//make _state as initially setup
}
我不喜欢这种解决方案。我缺少A *算法中的某些东西会有所帮助吗?我还没有完成任务,您是否看到一些即将到来的问题/需要提出的观点?
也许A *不是正确的算法,但我很乐意接受任何导致不同之处的事情。
PD:如果相关,则用于C#实现
答案 0 :(得分:0)
您可以通过将其存储在每个对象中而不是状态中,而是存储从导致该状态的初始状态开始的决策顺序,使它看起来更像普通A *。当您想处理一个状态时,请查看导致当前状态的决策顺序,将您需要进入的状态备份到公共祖先,然后查看记录的决策集。此类更改的成本最多是某些恒定因素乘以决策树的深度。如果这是高度分支和平衡的,则可能不会那么深。
另一种选择是https://en.wikipedia.org/wiki/Iterative_deepening_depth-first_search的某些版本或“有限差异搜索”,它使用到目前为止(来自先前迭代)找到的最佳答案以及A *启发式算法来避免节点不可能导致可能的答案。在修整一次(修整后)当前对差异或深度的限制并没有真正阻止您调查每个想要的节点时,您知道找到了最佳答案。