En yakın noktayı bulmak için algoritma


18

Enlem / boylamıyla birkaç yüz şehrin bir listesi var. Başka bir yer (ayrıca lat / uzun) göz önüne alındığında en yakın şehri bulmak gerekir.

Herhangi bir CBS kullanmadığım için, şimdiye kadar açık olan algoritma, noktalar arasındaki mesafeyi hesaplayarak tüm şehirler için bir döngü yapmaktır.

Döngüyü yapmak benim için uygulanabilir, ancak bunu daha verimli bir şekilde gerçekleştirmek için algoritma uygulamak kolay mı? Ya da bunu çözmeye yardımcı olabilecek hafif bir Java kütüphanesi mi?

Notlar : Tam bir CBS çözümüne veya ağır / karmaşık kütüphaneye ihtiyacım yok / istemiyorum. Daha az iyi ama en kolay ve daha hafif bir çözümü tercih ederim çünkü çözmem gereken tek şey bu.


Yani mesafenin doğru olmayacağı önemli değil mi? Ve bir şehri diğerinden daha ileriye götürebilecek yolları hesaba katmak istemiyor musunuz (diyagonal ve kare)?
Brad Nesom

Evet yollar benim için önemli değil. Hava tahminleri için doğrusal mesafeye en yakın şehre ihtiyacım var.
Lujop

1
Hava tahminleri? Umarım bir süper bilgisayar ve eğitimli meteorologlardan oluşan bir personelin hizmetinizdedir.
Michael Todd

Tahminler Michael, sadece en yakın olanı almak zorunda :)
lujop

Yanıtlar:


24

Bu soruyu 20 yıl önce bir masaüstü CBS tasarlarken araştırdım. Etkileşimli olarak noktadan noktaya mesafeleri bulmamız gerekiyordu; hedefimiz hesaplamaları binlerce nokta için 1/2 saniyeden daha kısa sürede yapmaktı. Testler (25 MHz 486 PC'de!) Tüm mesafeleri, tam olarak tarif ettiğiniz gibi (basit bariz algoritmayla) hesaplayabildiğimizi gösterdi, o kadar hızlı ki, dörtlü bir yapı gibi daha sofistike bir çözüm oluşturmanın hiçbir anlamı yoktu. .

Tek bir "prob" noktasına mesafeleri hesaplamak için seçenekleriniz şunları içerir: (a) tüm noktaları prob noktasında ortalanmış eşit mesafeli bir projeksiyon kullanarak yansıtmak veya (b) küresel bir dünya modeli benimsemek ve Haversine formülünü kullanmak . Birincisi, elipsoidal bir modelin doğruluğuna ihtiyacınız varsa uygundur. Her iki durumda da hesaplamalar oldukça hızlıdır, muhtemelen 1000'den az keneyi alır: tek bir işlemciyle saniyede yaklaşık milyon noktayı sorgulayabilirsiniz.

Senin için yeterince hızlı mı? Değilse, kaba kuvvet yöntemi kolayca paralel hale gelir ve doğrudan işlemci sayısı ile ölçeklendirilir: noktaları işlemciler arasında bölün ve ardından her işlemci tarafından bulunan en yakın olanın son karşılaştırmasını yapın.

Daha hızlı gitmeniz gerekiyorsa, noktaları görüntülemek için çeşitli yaklaşımlar kullanabilirsiniz. Örneğin, -88 ila +88 derece enlemindeyseniz ve şimdiye kadar bulunan en yakın nokta 200 km uzaklıktadırsa, enlemi prob noktasının enleminden 2 dereceden farklı olan herhangi bir nokta muhtemelen daha yakın olamaz (çünkü herhangi bir yerde toprak, bir enlem derecesi yaklaşık 110 km'yi aşıyor). Çoğu durumda bu tür ön tarama, saniyede yüz milyonlarca noktayı işlemenizi sağlayabilir.


1
Haversin formülü hakkında bir tartışma için bkz. Gis.stackexchange.com/q/4906/664
whuber

4

Basit bir döngünün "birkaç yüz şehir" için etkili olması gerektiği konusunda başkalarına katılıyorum.

Uygulamanız göz önüne alındığında, elipsoidal mesafelerle uğraşmak büyük olasılıkla aşırı derecede büyüktür - muhtemelen konumu birkaç metreye kadar inen hava tahminleriyle uğraşıyorsunuz. Küresel geometri, bunu döngünüzde kolayca yapabileceğiniz kadar basittir.

Daha da basit olabilir (örneğin; x olarak delta lat ve x olarak delta lon * cos (lat) kullanın ve minimum x ^ 2 + y ^ 2'yi bulun). Yalnızca bir kez hesapladığınız hedef enlemin kosinüsünü kullanıyorsunuz. Bu, uzak şehirler için giderek daha yanlış olacaktır, ancak yine de reddedilecekler, bu yüzden önemli değil. En yakın şehrinizin genellikle birkaç yüz kilometre içinde olduğunu varsayarsak, bunu daha doğru bir formül kullanarak farklı bir sonucun (en yakın şehir) kullanma şansı oldukça küçüktür ve yalnızca farklılıklar yeterince küçük olduğunda ortaya çıkar. doğru "muhtemelen yine de diğer faktörlere bağlı olacaktır (yani: gürültüde kayıp).

Gömülü bir sistem veya yavaş bir tercüman kullanmadığınız sürece, muhtemelen sadece başkalarının önerdiği küresel formları kullanabilirsiniz.


1

Bu, zaten söylenenlere ek olarak, ancak uygun bir veri yapısı seçmenin önemini not edeceğimi düşündüm. .NET'te bir K-Fonksiyonu için kendi kodumu yazdım ve verimli koleksiyonlar kullanmanın işleri önemli ölçüde hızlandırdığını buldum. Maalesef kesin hızlar için O gösterimini bilmiyorum. Nokta kimliği ile x ve y koordinatları için iki sözlük kullandım. Java bilmiyorum, bu yüzden hiçbir şey öneremedim.

Şerefe, David

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.