2016-08-23 17 views
5

Vấn đềhiệu quả tìm tọa độ cặp gần nhất từ ​​một bộ bằng Python

Hãy tưởng tượng tôi đang đứng trong sân bay. Với một cặp tọa độ địa lý, làm cách nào để xác định một cách hiệu quả sân bay nào tôi đang đứng?

Đầu vào

  • Một phối hợp cặp (x,y) đại diện cho vị trí tôi đang đứng ở.
  • Một tập hợp các cặp tọa độ [(a1,b1), (a2,b2)...] trong đó mỗi cặp tọa độ đại diện cho một sân bay.

mong muốn Output

Một phối hợp cặp (a,b) từ tập các sân bay phối hợp cặp đại diện cho các sân bay gần nhất với điểm (x,y).

không hiệu quả Giải pháp

Đây là nỗ lực không hiệu quả của tôi tại giải quyết vấn đề này. Nó rõ ràng là tuyến tính trong chiều dài của tập hợp các sân bay.

shortest_distance = None 
shortest_distance_coordinates = None 

point = (50.776435, -0.146834) 

for airport in airports: 
    distance = compute_distance(point, airport) 
    if distance < shortest_distance or shortest_distance is None: 
     shortest_distance = distance 
     shortest_distance_coordinates = airport 

Các Câu hỏi

Làm thế nào giải pháp này có thể được cải thiện? Điều này có thể liên quan đến một số cách lọc trước danh sách các sân bay dựa trên tọa độ của vị trí chúng tôi hiện đang đứng hoặc sắp xếp chúng theo thứ tự nhất định trước đó.

+0

Nó không thể được cải thiện đáng kể mà không cần bất kỳ bổ sung kiến ​​thức của vấn đề (ví dụ: một thực tế rằng có ít nhất một sân bay trong langtitude cùng thể đã trợ giúp). Để lọc các sân bay, bạn sẽ vẫn cần phải xem xét từng loại, vì vậy sự phức tạp của bạn sẽ ở lại O (n) (trừ khi, tất nhiên, bạn đang làm một điều gì đó phức tạp trong 'compute_distance()', mà tôi nghi ngờ vì bạn có lẽ chỉ cần làm khoảng cách Haversine) –

+1

Xem https://en.wikipedia.org/wiki/Nearest_neighbor_search để biết tổng quan về các thuật toán và cấu trúc dữ liệu. – NPE

+0

@DmitryTorba Cảm ơn bạn đã bình luận. Điều này có nhất thiết phải không? Nếu chúng ta sắp xếp danh sách trước theo một cách cụ thể thì sao? – Kieran

Trả lời

2

Nếu tọa độ của bạn là không được phân loại , tìm kiếm của bạn chỉ có thể được cải thiện một chút, giả sử rằng nó là (latitude,longitude) bằng cách lọc theo vĩ độ trước tiên cho trái đất

1 độ vĩ độ trên mặt cầu là 111,2 km hoặc 69 dặm

nhưng điều đó sẽ không đưa ra một sự tăng tốc rất lớn.

Nếu bạn sắp xếp các sân bay bởi vĩ độ đầu tiên sau đó bạn có thể sử dụng tìm kiếm nhị phân cho việc tìm kiếm các sân bay đầu tiên mà thể trận đấu (airport_lat >= point_lat-tolerance) và sau đó chỉ so sánh tới người cuối cùng mà thể trận đấu (airport_lat <= point_lat+tolerance) - nhưng chăm sóc 0 độ bằng 360. Trong khi bạn không thể sử dụng thư viện đó trực tiếp, các nguồn của bisect là một khởi đầu tốt để thực hiện tìm kiếm nhị phân.

Mặc dù về mặt kỹ thuật theo cách này, tìm kiếm vẫn là O (n), bạn có ít hơn nhiều tính toán khoảng cách thực tế (tùy thuộc vào dung sai) và so sánh một số vĩ độ.Vì vậy, bạn sẽ có một tốc độ rất lớn.

+0

Đây là câu trả lời hứa hẹn nhất cho đến nay. Thực hiện khôn ngoan, tôi đang lưu trữ các sân bay của tôi trong một cơ sở dữ liệu SQL. Vì vậy, tôi có thể thực hiện các truy vấn khoan dung ở cấp SQL và sau đó chạy thuật toán khoảng cách trên các kết quả. – Kieran

+0

Điều đó sẽ là tốt nhất vì nó nhanh hơn rất nhiều theo cách đó. (hoạt động tốt nhất nếu bạn có chỉ mục trên vĩ độ) – janbrohl

2

Từ SO question này:

import numpy as np 
def closest_node(node, nodes): 
    nodes = np.asarray(nodes) 
    deltas = nodes - node 
    dist_2 = np.einsum('ij,ij->i', deltas, deltas) 
    return np.argmin(dist_2) 

nơi node là một tuple với hai giá trị (x, y) và nodes là một mảng của bộ dữ liệu với hai giá trị ([(x_1, y_1), (x_2, y_2),])

+0

Mã này không có ý nghĩa nhiều ở đây trên chính nó . Có vẻ như nó đang cố gắng tối ưu hóa phép tính khoảng cách. Tôi đang tìm cách để giảm bớt danh sách các sân bay một cách nhanh chóng, bằng cách sắp xếp trước hoặc lọc trước. Hy vọng điều này có ý nghĩa. – Kieran

+0

Bạn đã hỏi _Làm thế nào để giải pháp này có thể được cải thiện? _ Và tôi đã trả lời bằng một đoạn mã đi _better_. Sau đó, nếu bạn muốn lọc một số, đó là một loại cải tiến khác (hay không), điều này không làm cho tôi bớt đi. @Kieran –

+0

Tôi cố ý bỏ qua chi tiết của 'compute_distance' - chúng tôi giả định rằng chúng tôi có phương pháp tính toán hiệu quả khoảng cách :) – Kieran

Các vấn đề liên quan