【发布时间】:2021-10-17 21:17:49
【问题描述】:
我正在用 Python 编写 Astar 算法的实现,有时我想选择 open_set 中具有最低 f_score value 的元素:
# current is the node in open_set having the lowest f_score value
current = min_f_score(open_set, f_score)
open_set 是元组 (x, y) 的列表,表示 2D 中点的坐标,f_score 是字典 {(x, y): score},它为每个元组 (x, y) 分配其 f_score 值。
我对@987654330@ 的第一个实现如下:
def min_f_score(open_set, f_score):
# First we initialize min_score_element and min_score
min_score_element = open_set[0]
min_score = f_score[open_set[0]]
# Then we look for the element from f_score keys with the lowest value
for element in open_set:
if element in f_score.keys() and f_score[element] < min_score:
min_score = f_score[element]
min_score_element = element
return min_score_element
它工作得很好,但我想知道我是否可以想出一些更精简、更 Python 的代码。经过一番研究,我想出了另外两个实现:
def min_f_score(open_set, f_score):
# We filter the elements from open_set and then find the min f_score value
return min(filter(lambda k: k in open_set, f_score), key=(lambda k: f_score[k]))
和:
def min_f_score(open_set, f_score):
# We look for the min while assigning inf value to elements not in open_set
return min(f_score, key=(lambda k: f_score[k] if k in open_set else float("inf")))
两者似乎都可以工作并给我相同的结果,但比第一个实现慢得多。
出于好奇,我想知道是否有更好的方法来实现min_f_score?
编辑:正如@azro 所建议的(谢谢),我正在添加一个要执行的代码示例:
open_set = [(1, 2), (1, 3), (2, 1), (2, 2), (3, 1), (1, 4), (4, 1), (1, 5), (5, 0), (5, 1), (0, 6), (1, 6)]
f_score = {(0, 0): 486.0, (0, 1): 308.0, (1, 0): 308.0, (1, 1): 265.0, (0, 2): 265.0, (1, 2): 338.0, (0, 3): 284.0, (1, 3): 450.0, (2, 0): 265.0, (2, 1): 338.0, (2, 2): 629.0, (3, 0): 284.0, (3, 1): 450.0, (0, 4): 310.0, (1, 4): 550.0, (4, 0): 310.0, (4, 1): 564.0, (0, 5): 316.0, (1, 5): 588.0, (5, 0): 316.0, (5, 1): 606.0, (0, 6): 298.0, (1, 6): 534.0}
min_f_score(open_set, f_score)
输出:(0, 6)
【问题讨论】:
-
如果能提供一个可重现的示例,我们可以粘贴并运行代码,那就太好了,谢谢
-
您的第一个实现的优点是可读性强且易于理解
-
嗯,为什么open_set不是集合?
-
@StefanPochmann 这是个好问题。至少这是一个很好的例子,为什么在名称中包含变量的类型是不好的。
-
在您的示例数据中,
open_set是f_score的子集,大约是其一半。它是否始终是一个子集,并且是您一般情况的一半大小?
标签: python list dictionary key-value minimum