假设您有一个用字典表示的大网格。在某些坐标处有“玩家”,而其他坐标为空。字典
d = {(500,100): "player1", (480, 230): "player"}
(这些是玩家在网格中的位置)。
现在,如果您的坐标为(500,90),那么两个玩家中哪个最接近?我知道勾股定理必须以某种方式实现才能解决,但是我不知道如何在函数中实现。 这是我走过的最远的地方:
d = {(500,100): "player1", (480, 230): "player"}
def nearest_player(grid, x-cor, y-cor):
'''print out (500,100) as the answer'''
任何想法都将不胜感激。
答案 0 :(得分:3)
选项1:蛮力
蛮力解决方案可能是搜索所有玩家并选择最接近的玩家:
# I renamed x-cor to x, and y-cor to y since these were not valid python names
def nearest_player(grid, x, y):
best_distance = float('inf')
best_player = None
for pos, player in grid.items():
# I actually use squared distance since this is
# equivalent to the "real" distance
distance = (pos - x) ** 2 + (pos - y) ** 2
if distance < best_distance:
best_distance = distance
best_player = player
return best_player
选项2
更优雅的方法如下:
def nearest_player(grid, x, y):
distances = [(pos - x) ** 2 + (pos - y) ** 2 for pos in grid]
return grid.values()[distances.index(min(distances))]
我在这里做什么?
首先,您计算所有距离:
distances = [(pos - x) ** 2 + (pos - y) ** 2 for pos in grid]
这将产生一个具有所有距离的数组。 然后计算其最小值的索引:
distances.index(min(distances))
将赋予您的grid
的值列表会给玩家:
grid.values()[distances.index(min(distances))]
和瞧:)
旁注:进一步走
只是为了大脑使用(我不知道这是否是正确的英语)。
假设您的实际键不是坐标,而是不同的坐标(str
,您需要计算Levenshtein distance)。您可以执行以下操作:
def nearest(data, item, d):
distances = [d(item, i) for i in data]
return data.values()[distances.index(min(distances))]
,实际上您需要提供一个函数d
(用于距离),该函数计算两个项目之间的距离。就是这样。
在您当前的情况下,d
为:
def euclidean_distance(x, y):
return sum((x[i] - y[i]) ** 2 for i in range(0, len(x)))
如果您以x
或y
的形式提供tuple
和list
。
答案 1 :(得分:1)
Using numpy norm:
In[9] newd = {np.linalg.norm(np.array(i)-np.array(c)):v for i, v in d.items()}
In [10]: newd
Out[10]: {10.0: 'player1', 141.4213562373095: 'player'}
In [12]: newd[min(newd)]
Out[12]: 'player1'
答案 2 :(得分:0)
与其他解决方案类似,只是因素有所不同。
import groovy.json.JsonBuilder
def data = [
Rule: [
RuleId:0,
Devices:[1,2,3]
]
]
println new JsonBuilder(data).toPrettyString()
我不确定字典是否适合您的目的。列表列表会更自然。
答案 3 :(得分:0)
It turns out you can do argmin
in pure Python with min(iterable, key=f)
, where f
is the function to be minimised. So:
d = {(500,100): "player1", (480, 230): "player2"}
target_location = (500, 90)
def square_distance(v1, v2):
return sum((x1 - x2)**2 for x1, x2 in zip(v1, v2))
nearest_location = min(d, key=lambda location: square_distance(location, target_location))
nearest_player = d[nearest_location]