簡體   English   中英

算法找到附近的朋友?

[英]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

其中phiomega是與您所需距離相對應的緯度和經度。 這將取決於你在地球上的位置,但有確定的方程式來計算它。 您的數據庫也可能為您進行這些計算。


老答案。

我會看四叉樹kd樹

我相信,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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM