我很难跟踪getAdjacentTiles(..)
生成的磁贴。我已经确定了下面的A*实现的性能问题是,我没有跟踪以前看到的分片,每次调用getAdjacentTiles
都会返回新的分片(Node
),而不是{getAdjacentTiles
,以确定它生成的分片是否已被访问过。在
我的问题是,我似乎无法正确地跟踪这些瓷砖。每当我的A*需要超过4次移动才能到达end
位置时,它就会失败。我确信这与我如何跟踪这些分片有关(同样是Node
)我会怀疑问题出在我对python的知识上,是否允许我像在getAdjacentTiles(...)
中循环使用allTiles
集一样做.apped(tile)
?在
Here's a link to the question that led me to this one
生成的错误(有时,仅当A*路径超过约3步时….)
File "P3.py", line 67, in aStar
openSet.remove(curNode)
KeyError: <__main__.Node instance at 0xa39edcc>
来源
^{pr2}$
让我们启动交互式解释器看看能找到什么。(问题中没有给出类的名称,所以我将其命名为
Search
。)好的,第一个问题是这些
^{pr2}$Node
实例不是自解释的。我们无法对“Node instance at 0x104895518”执行任何操作,因此让我们向Node
类添加一个__repr__
方法:然后再试一次:
好吧,这更能说明问题。让我们启动Python debugger并执行postmortem:
所以节点已经关闭了。怎么会这样?如果节点被添加到}两次,就会发生这种情况。然后它将从
openSet
和{openHeap
弹出两次(因为堆可以有多个相同的项),但只能从openSet
中删除一次。相关代码如下所示:第一个问题是,尽管您费尽心思给出了}方法,但还是推送了
__lt__
和{(cost, t)
对。相反,只需将t
推到堆上:这需要在其他地方进行一些更改:而不是
你得写信了
^{8}$现在,第二个问题(这是我的错,抱歉),是如果
t
已经在openSet
中,那么我们就不应该再将它添加到堆中。相反,我们应该恢复健康:回到调试器输出,回想一下:
这应该让你担心:成本不应该总是整数吗?看来成本计算还是错的。上面写着:
但第三行应该说:
因此,在所有这些修复工作就绪后,让我们再试一次:
回复评论
“您是如何从翻译程序调用
Search().aStar(...)
?”我运行解释器,然后在解释器提示符处输入这行代码。See the tutorial。“所以欧几里德距离永远是1。”是的,如果你在一个统一的成本网格中搜索路径,那么相邻之间的欧几里德距离总是相同的。
“现在我考虑一下,
curNode.cost - self.manHatDist(curNode.pos, end)
总是等于零。”这是不对的。在您的实现中,搜索节点的cost
是(i)从一开始到达该节点的成本,加上(ii)从该节点到达终点的成本的可接受估计值。所以,如果你减去可容许的估计值,你应该又回到(i)。相关问题 更多 >
编程相关推荐