我正在为http://aichallenge.org/specification.php实现A*算法,并想知道一种巧妙的方法来基于施瓦茨变换选择集合中的最小值。
基本上,我有一组合适的移动目标方格,我想移动到成本最低的方格。
基本上,我将在循环中从我的邻居中选择成本最低的方格。
我唯一能想到的方法是类似这样的:
next_spot = spot.neighbors.sort_by |a,b| { a.cost(dest) <=> b.cost(dest) }.first
但我真的很想要一些更高性能的东西,因为我不想真的对集合进行排序,我只是想要具有最小变换值的那个。
请注意,我可以编写一些更冗长和“C风格”的循环,并跟踪之前的最小值,但我希望得到一些清晰而简洁的东西。
回答:
为什么不使用min_by
?
next_spot = spot.neighbors.min_by { |x| x.cost(dest) }
如果某个类似 Enumerable 的方法没有 “_by” 版本,你可以使用传统的施瓦茨变换,通过这种伪 Ruby 模式手动完成:
a.map { |x| [ expensive(x), x ] }. # 执行耗时部分一次并缓存结果 op { |x| something_with x.first... }. # 执行你真正想要做的事情 map { |x| x.last } # 解包缓存