निकटतम बिंदु खोजने के लिए एल्गोरिदम


18

मेरे पास उनके अक्षांश / देशांतर के साथ कुछ सौ शहरों की सूची है। अन्य स्थान को देखते हुए (लेट / लॉन्ग में भी) मुझे निकटतम शहर खोजने की आवश्यकता है।

जैसा कि मैंने किसी भी जीआईएस का उपयोग नहीं किया है, अब तक स्पष्ट एल्गोरिदम सभी शहरों के लिए एक लूप बनाना है, जो अंकों के बीच की दूरी की गणना करता है।

लूप बनाना मेरे लिए व्यावहारिक है, लेकिन अधिक कुशलतापूर्वक पूरा करने के लिए एल्गोरिथ्म को लागू करना कुछ आसान है? या कुछ हल्के जावा पुस्तकालय जो इसे हल करने में मदद कर सकते हैं?

नोट : मुझे संपूर्ण जीआईएस समाधान या भारी / जटिल पुस्तकालय की आवश्यकता नहीं है / चाहिए। मैं कम अच्छा लेकिन सबसे आसान और हल्का समाधान पसंद करता हूं क्योंकि यही एकमात्र चीज है जिसे मुझे हल करने की आवश्यकता है।


तो यह कोई फर्क नहीं पड़ता कि दूरी सही नहीं होगी? और आप उन सड़कों के लिए जिम्मेदार नहीं हैं जो एक शहर को दूसरे (विकर्ण बनाम वर्ग) से आगे बना सकती हैं?
ब्रैड नेसोम

हां सड़कें मेरे लिए महत्वपूर्ण नहीं हैं। मुझे रैखिक दूरी में निकटतम शहर की आवश्यकता है क्योंकि यह मौसम की भविष्यवाणियों के लिए है।
लूजोप

1
मौसम की भविष्यवाणी? मुझे आशा है कि आपके पास अपने निपटान में एक सुपर कंप्यूटर और प्रशिक्षित मौसम विज्ञानियों का एक कर्मचारी होगा।
माइकल टॉड

भविष्यवाणियों माइकल किया जाता है, केवल मैं निकटतम एक लेने के लिए है :)
lujop

जवाबों:


24

मैंने 20 साल पहले डेस्कटॉप जीआईएस डिजाइन करते समय इस प्रश्न की बिल्कुल जांच की थी। हमें पॉइंट-टू-पॉइंट दूरी को अंतःक्रियात्मक रूप से खोजने की आवश्यकता थी; हमारा लक्ष्य हजारों अंकों के लिए 1/2 सेकंड से भी कम समय में गणना करना था। परीक्षण (एक 25 मेगाहर्ट्ज 486 पीसी पर!) ने दिखाया कि हम सभी दूरियों की गणना कर सकते हैं, ठीक उसी तरह जैसे आप वर्णन करते हैं (सरल स्पष्ट एल्गोरिथ्म के साथ), इतनी जल्दी कि यह एक अधिक परिष्कृत समाधान बनाने के लिए कोई मतलब नहीं था, जैसे कि क्वाडट्री संरचना। ।

एक एकल "जांच" बिंदु पर दूरियों की गणना के लिए आपके विकल्पों में शामिल हैं (क) जांच बिंदु पर केंद्रित एक समभुज प्रक्षेपण का उपयोग करके सभी बिंदुओं को प्रक्षेपित करना या (ख) एक गोलाकार पृथ्वी मॉडल को अपनाना और हैवरसाइन सूत्र का उपयोग करना । यदि आप एक दीर्घवृत्त मॉडल की सटीकता की आवश्यकता है तो पहला उपयुक्त है। या तो मामले में गणना काफी तेजी से होती है, संभवतः 1000 से कम टिक्स ले रहे हैं: आप एक सिंगल प्रोसेसर के साथ एक मिलियन पॉइंट सेकंड के आसपास क्वेरी कर सकते हैं।

आपके लिए काफी उपवास है? यदि नहीं, तो ब्रूट-फोर्स विधि आसानी से समानांतर हो जाती है और प्रोसेसर की संख्या के साथ सीधे स्केल करती है: बस प्रोसेसर के बीच के बिंदुओं को विभाजित करें और फिर प्रत्येक प्रोसेसर द्वारा पाए गए निकटतम निकटतम की अंतिम तुलना करें।

यदि आपको तेजी से जाने की आवश्यकता है, तो आप स्क्रीन अंक के लिए विभिन्न सन्निकटन का उपयोग कर सकते हैं। उदाहरण के लिए, यदि आप -88 और +88 डिग्री अक्षांश के बीच हैं और अब तक मिला निकटतम बिंदु 200 किमी दूर है, तो कोई भी बिंदु जिसका अक्षांश जांच बिंदु के अक्षांश से 2 डिग्री से अधिक है, संभवतः निकट नहीं हो सकता (क्योंकि कहीं पर भी) पृथ्वी, अक्षांश का एक अंश लगभग 110 किमी से अधिक है)। कई मामलों में इस तरह की प्री-स्क्रीनिंग आपको लाखों-करोड़ों बिंदुओं को एक सेकंड में संसाधित करने में सक्षम बनाती है।


1
Haversine सूत्र देखने की चर्चा के लिए gis.stackexchange.com/q/4906/664
whuber

4

मैं दूसरों से सहमत हूं कि एक साधारण लूप "कुछ सौ शहरों" के लिए प्रभावी होना चाहिए।

आपके आवेदन को देखते हुए, दीर्घवृत्तीय दूरियों से निपटना संभवतया प्रमुख ओवरकिल है - आप शायद मौसम की भविष्यवाणियों के साथ काम कर रहे हैं, जिसका इलाका शायद ही कुछ मीटर नीचे हो। गोलाकार ज्यामिति इतनी सरल है कि आप आसानी से अपने पाश में कर सकते हैं।

यह और भी सरल हो सकता है (उदाहरण के लिए, डेल्टा लैट का उपयोग करें y और डेल्टा लॉन के रूप में * कॉस (lat) के रूप में x और न्यूनतम x ^ 2 + y ^ 2 का पता लगाएं)। आप लक्ष्य अक्षांश के कोसाइन का उपयोग कर रहे हैं, जिसे आप केवल एक बार गणना करते हैं। यह दूर के शहरों के लिए तेजी से गलत होगा, लेकिन वे वैसे भी अस्वीकार कर दिए जाएंगे इसलिए कोई फर्क नहीं पड़ता। यह मानते हुए कि आपका निकटतम शहर आम तौर पर एक दो सौ किलोमीटर के भीतर है, एक अलग परिणाम (निकटतम शहर) की संभावना इस बनाम का उपयोग करके अधिक सटीक सूत्र का उपयोग करना काफी छोटा है और केवल तब होता है जब मतभेद छोटे होते हैं कि "जो पूर्वानुमान अधिक है सटीक "शायद वैसे भी अन्य कारकों पर निर्भर करेगा (यानी: शोर में खो गया)।

जब तक आप एक एम्बेडेड सिस्टम या धीमे दुभाषिया का उपयोग नहीं कर रहे हैं, आप संभवतः केवल गोलाकार औपचारिकताओं का उपयोग कर सकते हैं जो अन्य लोग सुझाव दे रहे हैं, थो।


1

यह पहले से ही कहा गया है के अलावा है, लेकिन मुझे लगा कि मैं एक उपयुक्त डेटा संरचना चुनने के महत्व पर ध्यान दूंगा। मैंने अपने स्वयं के कोड को .NET में के-फंक्शन के लिए लिखा था, और पाया कि कुशल संग्रह का उपयोग करने से चीजों में काफी वृद्धि होती है। क्षमा करें, मुझे सटीक गति के लिए O अंकन ज्ञात नहीं है। मैंने x और y के लिए दो डिक्शनरों का उपयोग बिंदु आईडी के साथ एक कुंजी के रूप में किया। मुझे नहीं पता जावा कुछ भी सुझाव नहीं दे सकता है।

चीयर्स, डेविड

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.