Thuật toán tìm điểm gần nhất


18

Tôi có một danh sách vài trăm thành phố có vĩ độ / kinh độ. Đưa ra một địa điểm khác (cũng trong lat / long) tôi cần tìm thành phố gần nhất.

Vì tôi không sử dụng bất kỳ hệ thống GIS nào, nên bây giờ thuật toán rõ ràng là tạo một vòng lặp cho tất cả các thành phố, tính toán khoảng cách giữa các điểm.

Làm cho vòng lặp là có thể đối với tôi, nhưng có một số thuật toán dễ thực hiện để thực hiện điều đó hiệu quả hơn? Hoặc một số thư viện Java nhẹ có thể giúp giải quyết điều đó?

Lưu ý : Tôi không cần / muốn một giải pháp GIS hoàn chỉnh hoặc thư viện nặng / phức tạp. Tôi thích một giải pháp ít tốt hơn nhưng dễ nhất và nhẹ hơn bởi vì đó là điều duy nhất mà tôi cần phải giải quyết.


Vì vậy, không có vấn đề rằng khoảng cách sẽ không chính xác? Và bạn không muốn tính đến những con đường có thể khiến một thành phố xa hơn một thành phố khác (đường chéo so với hình vuông)?
Brad Nesom

Có đường không quan trọng với tôi. Tôi cần thành phố gần nhất trong khoảng cách tuyến tính bởi vì đó là dự đoán thời tiết.
lujop

1
Dự báo thời tiết? Tôi hy vọng bạn có một siêu máy tính và một đội ngũ các nhà khí tượng học được đào tạo theo ý của bạn.
Michael Todd

Các dự đoán đã được Michael thực hiện, chỉ tôi mới lấy cái gần nhất :)
lujop

Câu trả lời:


24

Tôi đã điều tra chính xác câu hỏi này 20 năm trước khi thiết kế một máy tính để bàn. Chúng tôi cần phải tìm khoảng cách điểm-điểm tương tác; mục tiêu của chúng tôi là thực hiện các tính toán trong chưa đầy 1/2 giây cho hàng ngàn điểm. Thử nghiệm (trên PC 486 48 MHz!) Cho thấy chúng tôi có thể tính toán tất cả các khoảng cách, chính xác như bạn mô tả (với thuật toán rõ ràng đơn giản), nhanh đến mức không có ý nghĩa gì để tạo ra một giải pháp phức tạp hơn, chẳng hạn như cấu trúc tứ giác .

Để tính toán khoảng cách đến một điểm "thăm dò" duy nhất, các tùy chọn của bạn bao gồm (a) chiếu tất cả các điểm bằng phép chiếu tương đương tập trung tại điểm thăm dò hoặc (b) áp dụng mô hình trái đất hình cầu và sử dụng công thức Haversine . Đầu tiên là thích hợp nếu bạn cần độ chính xác của mô hình ellipsoidal. Trong cả hai trường hợp, các phép tính đều nhanh chóng, có thể mất ít hơn 1000 tick: bạn có thể truy vấn khoảng một triệu điểm mỗi giây với một bộ xử lý.

Đủ nhanh cho bạn? Nếu không, phương pháp brute-force song song dễ dàng và chia tỷ lệ trực tiếp với số lượng bộ xử lý: chỉ cần chia điểm cho các bộ xử lý và sau đó thực hiện so sánh cuối cùng với điểm gần nhất được tìm thấy bởi mỗi bộ xử lý.

Nếu bạn cần đi nhanh hơn, bạn có thể sử dụng các xấp xỉ khác nhau cho các điểm trên màn hình. Ví dụ: nếu bạn ở giữa vĩ độ -88 đến +88 độ và điểm gần nhất được tìm thấy cách đó 200 km, thì bất kỳ điểm nào có vĩ độ khác với vĩ độ của điểm thăm dò hơn 2 độ không thể gần hơn (bởi vì bất cứ nơi nào trên trái đất, một độ vĩ độ vượt quá khoảng 110 km). Trong nhiều trường hợp, loại sàng lọc trước này có thể cho phép bạn xử lý hàng trăm triệu điểm mỗi giây.


1
Để thảo luận về công thức haversine,
whuber

4

Tôi đồng ý với những người khác rằng một vòng lặp đơn giản sẽ có hiệu quả đối với "vài trăm thành phố".

Với ứng dụng của bạn, việc xử lý các khoảng cách ellipsoidal có lẽ là quá mức cần thiết - bạn có thể đang đối phó với các dự đoán thời tiết mà địa phương khó xuống đến vài mét. Hình học hình cầu đủ đơn giản để bạn có thể dễ dàng thực hiện điều đó trong vòng lặp của mình.

Nó thậm chí có thể đơn giản hơn (ví dụ: sử dụng delta lat như y và delta lon * cos (lat) là x và tìm tối thiểu x ^ 2 + y ^ 2). Bạn đang sử dụng cosin của vĩ độ đích, mà bạn chỉ tính một lần. Điều này sẽ ngày càng không chính xác đối với các thành phố xa xôi, nhưng dù sao chúng cũng sẽ bị từ chối. Giả sử rằng thành phố gần nhất của bạn thường trong phạm vi vài trăm km, khả năng kết quả khác (thành phố gần nhất) sử dụng công thức này chính xác hơn là khá nhỏ và sẽ chỉ xảy ra khi sự khác biệt đủ nhỏ để "dự báo là nhiều hơn chính xác "có thể sẽ phụ thuộc vào các yếu tố khác (ví dụ: bị mất trong tiếng ồn).

Trừ khi bạn đang sử dụng một hệ thống nhúng hoặc một trình thông dịch chậm, bạn có thể đủ khả năng để chỉ sử dụng các hình thức hình cầu mà người khác đang đề xuất, tho.


1

Điều này ngoài những gì đã được nói, nhưng tôi nghĩ tôi sẽ lưu ý tầm quan trọng của việc chọn một cấu trúc dữ liệu phù hợp. Tôi đã viết mã riêng của mình cho Hàm K trong .NET và thấy rằng việc sử dụng các bộ sưu tập hiệu quả đã tăng tốc đáng kể. Xin lỗi tôi không biết ký hiệu O cho tốc độ chính xác. Tôi đã sử dụng hai Từ điển cho tọa độ x và y với ID điểm làm khóa. Tôi không biết Java nên không thể đề xuất bất cứ điều gì.

Chúc mừng, David

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.