我编写了一个BFS(广度优先搜索)路径规划算法。它与小网格(例如15乘15)完美配合,但是当涉及更大的网格(例如150乘250)时,这是一个灾难。使用 tic 和 toc 命令,我发现它花费的时间最多(效率最低的位),问题在于嵌套的for循环。我知道使用嵌套for循环被认为是坏的,我需要帮助用其他东西替换它(如果可能的话,避免使用循环)。
for j=1:length(F)
for k = 1:length(Closed)
if(F(j) == Closed(k))
F(j) = 0;
end
end
end
Closed = [Closed current];
代码的这一部分的目的是替换作为父节点的 F 的元素(我们来自哪里)。这样就可以忽略任何重复。
注意:我使用8连接空间,因此 n 总是小于8.
已关闭作为空向量启动,用于存储已访问节点列表(通过水平连接)。
当前是1到37901之间的数字,代表当前节点。
我知道有关于嵌套循环的另一个question,但我的问题是不同的。谢谢你的帮助!
答案 0 :(得分:0)
这段代码很慢的原因并不是你有嵌套循环,而是你实现了O(n 2 )算法。
您应该使用逻辑数组来指示“已关闭”的节点。这将使查找更有效。
考虑您有N = 37901
个节点。因此,初始化Closed
数组:
Closed = false(1,N);
现在要检查节点F(j)
是否已关闭,您只需执行Closed(F(j))
,如果已关闭则为true
。
现在您的循环可以替换为
F(Closed(F)) = [];
Closed(current) = true;
因为Closed(F)
是一个与F
大小相同的数组,对于封闭节点是正确的。您可以使用此数组索引到F
,并删除所有已关闭的节点。我正在删除这些节点,而不是为它们分配0,这样F
总是可以用来索引Closed
。如果我们在那里写0,它就不再是逻辑数组。如果您不需要更改F
的形状,则必须在编制索引之前进行一些额外的测试。
请注意,Closed = [Closed current]
也比Closed(current) = true
慢很多,因为它创建了一个新的数组,旧的Closed
数组被复制到其中。
请注意,你可以删除代码中的嵌套循环,如下所示,但它不一定会更快,因为算法仍然是O(n 2 )(你要比较每个F
中每个元素的Closed
中的元素。
for j=1:length(F)
if any(F(j) == Closed)
F(j) = 0;
end
end