【发布时间】:2016-02-14 20:00:22
【问题描述】:
我编写了一个使用 A* 算法解决 N-Puzzle 的程序。该算法运行良好,但与使用相同算法解决相同问题的所有程序相比,它似乎慢得多。 我认为减慢我的代码的部分是检查新节点是否存在于打开和关闭的列表中。 本质上,我正在做的是检查特定节点的整个值数组,每个节点都存储在 Closed 和 open 列表中。 这是我认为导致速度变慢的代码 sn-p。
for(auto temp_Node:Neighbours(process))
{
auto pred = [temp_Node](Node* item) //lambda Expression for 'pred', custom comparator
{
bool value=true;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
{
if(item->Grid[i][j]!=temp_Node->Grid[i][j])
{
value=false;
break;
}
}
if(item->g!=temp_Node->g)
value=false;
return value;
};
if(find_if(begin(closed_list),end(closed_list), pred)==end(closed_list))
{
auto open_list_cpy=find_if(begin(open_list),end(open_list), pred);
if(open_list_cpy==open_list.end())
{
open_list.insert(temp_Node);
}
如您所见,我使用带有 find_if 的 lambda 表达式来检查每个节点中的所有值。
我想知道我是否遗漏了什么,或者是否有任何其他更有效的方法来解决这个问题,或者这是应该如何完成的,而我的代码的其他部分有问题?
【问题讨论】:
-
将封闭列表维护为一个集合,其中查找是 O(1) 而不是您的代码实现的 O(n)。
-
封闭列表查找已使用下面的代码减少到 O(log(n)),如何减少到 O(1)?我不认为这是可能的,是吗!?
-
任何基于哈希表的集合实现在合理假设下都有一个摊销的 O(1) 成员资格测试。参见例如cplusplus.com/reference/unordered_set/unordered_set
-
所以在这种情况下,我必须找到一个重复的
NxN grid,你是说把整个Grid作为 Key 吗?因为查找网格将是 O(1)。 -
@Gene 我尝试将我的
closed_list实现为unordered_set,但我无法为二维整数数组(Grid)提供哈希函数。您能否建议一个哈希函数或将我引导至包含类似信息的页面?
标签: algorithm performance c++11 optimization a-star