[英]algorithm to find the nearby friends?
我有一個python程序坐在服務器端管理用戶位置信息,每個朋友有一對(經度,緯度),給定(經度,緯度)點,我如何有效地找到附近(比如在5KM以內)的朋友?
我有10K用戶在線...
謝謝。 箱子
新答案:
我會將lat和long存儲在單獨的列中。 在它們上放置索引。 然后,當你想找到特定用戶的附近朋友時,只需要做類似的事情
select field1, field1, ..., fieldn from users
where
user_lat > this_lat - phi and user_lat < this_lat + phi
and
user_lon > this_lon - omega and user_lon < this_lon + omega
其中phi
和omega
是與您所需距離相對應的緯度和經度。 這將取決於你在地球上的位置,但有確定的方程式來計算它。 您的數據庫也可能為您進行這些計算。
老答案。
我相信,Kd樹將成為這里的規范解決方案。
一種簡單的方法是沿着長度對點進行排序,然后,當查找朋友時,找到可能匹配的最小和最大長度。 對列表進行排序是O(n log n),查找朋友是線性的,但僅適用於長度范圍內的朋友。 以下是平面2D曲面上所有點的情況示例:
# friends is the sorted list of (x, y) tuples, (px, py) is my location
def get_near(friends, px, py, maxdist):
i1 = bisect.bisect_left(friends, (px - maxdist, py))
i2 = bisect.bisect_right(friends, (px + maxdist, py))
return [(x, y) for (x, y) in friends[i1:i2] if math.hypot(px - x, py - y) < maxdist]
對於經度/緯度情況,您必須使用另一個函數來測試距離而不是歐氏距離(math.hypot)。
制作一個詞典{graticule:[users]}(“經緯網”是1度緯度x經度1度的塊;所以你基本上只能對值進行舍入)。 要查找附近的用戶,首先從相同和相鄰的經緯網獲取用戶(因為目標可能在邊緣附近),然后使用基本邊界框測試過濾它們(即,對於某人內部可能的最小經度/緯度是多少?所需的半徑),然后做一個詳細的測試(如果你需要准確性,那么你需要一些比Pythagoras更復雜的數學)。
http://www.movable-type.co.uk/scripts/latlong.html在效率方面,唯一真正想到的是在數據庫中輸入條目時預先計算距離,即有另一個表存儲一對位置以及距離,對於添加時添加的每個位置,您需要計算它與系統中每個其他點的距離的成本,但隨后在此表上查找可以快速解析一定的距離。
Aaronasterling的答案似乎是我自己想要思考的但是不知道存在:)所以它可能是一個更好的解決方案,但我相信你會在搜索時使用該算法產生一些開銷(雖然可能因為通常遍歷一棵樹,只要它合理平衡通常是一個相當快的過程,我需要一些時間才能確切地了解樹是如何組成的,這對我來說是一個新的概念)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.