2013-06-09 4 views
36

मैं एक ऐसे अनुप्रयोग पर काम कर रहा हूं जो Djikstra के एल्गोरिदम को प्रदर्शित करता है, और इसका उपयोग करने के लिए, मुझे अपने तत्वों के मूल्य में कमी होने पर ढेर संपत्ति को पुनर्स्थापित करने की आवश्यकता है।मिनी-हीप आधारित प्राथमिकता कतार के लिए ओ (लॉगन) कमी-कुंजी ऑपरेशन को कैसे कार्यान्वित करें?

जटिलता के बारे में समस्या यह है कि जब एल्गोरिथ्म एक तत्व के मूल्य में परिवर्तन, आंतरिक संरचना में उस तत्व के सूचकांक (इस मामले में ढेर) प्राथमिकता कतार के लिए इस्तेमाल किया अज्ञात है। इस तरह, मुझे इंडेक्स को पुनर्प्राप्त करने के लिए वर्तमान में ओ (एन) खोज करने की आवश्यकता है, इससे पहले कि मैं वास्तविक कम-कुंजी निष्पादित कर सकूं।

इसके अलावा, मैं ऑपरेशन के लिए आवश्यक वास्तविक कोड के बारे में बिल्कुल निश्चित नहीं हूं। मैं अपनी प्राथमिकता कतार के लिए डी-हीप here का उपयोग कर रहा हूं। स्यूडोकोड मदद करेगा, लेकिन जावा में एक उदाहरण पसंद करेंगे कि यह कैसे किया जाना चाहिए।

+1

http://en.m.wikipedia.org/wiki/Dijkstra's_algorithm#Running_time देखें। –

+8

उपर्युक्त लिंक से: "एक वेनिला बाइनरी ढेर पर कमी-कुंजी चरण में ओ (| वी |) लुक-अप से बचने के लिए, हेप के इंडेक्स में प्रत्येक चरम पर मैपिंग एक पूरक इंडेक्स को बनाए रखना आवश्यक है (और इसे जारी रखें प्राथमिकता कतार जी परिवर्तन के रूप में दिनांक), इसे इसके बजाय केवल ओ (लॉग | वी |) समय लेते हैं। " – Brainstorm

+0

@ ब्रेनस्टॉर्म मैंने मैपिंग का उपयोग करने पर विचार किया लेकिन मैं अन्य परिचालनों पर होने वाले प्रभाव के बारे में चिंतित था। मुझे लगता है कि यह एकमात्र तरीका है हालांकि इसे किया जा सकता है। – jathanasiou

उत्तर

23

आप निम्न कार्य कर सकते हैं: अपने ढेर के अंदर एक हैशपैप स्टोर करें जो आपके ढेर मूल्य इंडेक्स को ढेर करने के लिए मानचित्र करता है। तो फिर आप अपने सामान्य ढेर-तर्क का विस्तार करना चाहिए सिर्फ एक सा:

on Swap(i, j): 
    map[value[i]] = j; 
    map[value[j]] = i; 

on Insert(key, value): 
    map.Add(value, heapSize) in the beginning; 

on ExtractMin: 
    map.Remove(extractedValue) in the end; 

on UpdateKey(value, newKey): 
    index = map[value]; 
    keys[index] = newKey; 

BubbleUp(index)DecreaseKey के मामले में, और BubbleDown/Heapify(index)IncreaseKey के मामले में , मिनी-हीप-प्रोपे को बहाल करने के लिए rty। http://pastebin.com/kkZn123m

सम्मिलित और ExtractMin कॉल स्वैप लॉग (एन) के समय, जब बहाल ढेर संपत्ति:

यहाँ मेरी सी # कार्यान्वयन है। और आप स्वैप करने के लिए ओ (1) ओवरहेड जोड़ रहे हैं, इसलिए दोनों ऑपरेशन ओ रहे हैं (लॉग (एन))। UpdateKey भी लॉग (एन) है: पहले आप ओ (1) के लिए हैशैप में इंडेक्स को लुकअप करते हैं, फिर आप ओ (लॉग (एन)) के लिए हीप प्रॉपर्टी को पुनर्स्थापित कर रहे हैं जैसा कि आप Insert/ExtractMin में करते हैं।

महत्वपूर्ण नोट: इंडेक्स लुकअप के लिए मूल्यों का उपयोग करने के लिए आवश्यक है कि वे अद्वितीय हैं। यदि आप इस स्थिति के साथ ठीक नहीं हैं, तो आपको अपने कुंजी-मूल्य जोड़े में कुछ अद्वितीय आईडी जोड़नी होगी और मूल्य-अनुक्रमणिका मैपिंग के बजाय इस अद्वितीय आईडी और ढेर इंडेक्स के बीच मैपिंग बनाए रखना होगा। लेकिन डिजस्ट्रा के लिए इसकी आवश्यकता नहीं है, क्योंकि आपके मान ग्राफ़ नोड्स होंगे और आप अपनी प्राथमिकता कतार में डुप्लिकेट नोड्स नहीं चाहते हैं।

+2

आप अनुपस्थिति के लिए 'सरणी [vertex id] = heap अनुक्रमणिका' या '-1' जैसे सरणी का भी उपयोग कर सकते हैं। इसमें अधिक मेमोरी लग सकती है, लेकिन यह हैशपैप (कोई आकार बदलने, संघर्ष) की तुलना में तेज़ और सरल है। और स्मृति इससे कोई फर्क नहीं पड़ता क्योंकि आपको पहले से ही किसी सरणी में ग्राफ़ रखना है, जिससे कि प्रत्येक वर्टेक्स के लिए बस एक और 'int' जोड़ दिया जाएगा। –

+1

@Ciro - आपने जो वर्णन किया है वह प्रत्यक्ष पहुंच हैशटेबल है, लेकिन इसके उपयोग के लिए आपके प्रत्येक तत्व "हैश" को 0 और एन -1 के बीच एक अद्वितीय मान के लिए आवश्यक है। यदि आपके शिखरों में "वर्टेक्स आईडी" नहीं है और आप गतिशील रूप से उन शीर्षकों में विशेषताओं को जोड़ना नहीं चाहते हैं जिन्हें आप वेनिला सरणी का उपयोग नहीं कर सकते हैं। यदि आप इस तरह की एक विशेषता जोड़ सकते हैं तो आप वैसे भी एक "हीप इंडेक्स" विशेषता जोड़ना बेहतर होगा। एक हैशटेबल ओ जे (1) परिचालन पर समय के साथ सामान्य समाधान है और कोई आकार बदलने वाला नहीं होगा। – Dave

+0

@ डेव क्यों कोई आकार बदलना नहीं होगा? –

13

प्रति this SO question डिजस्ट्रा के एल्गोरिदम को लागू करने के लिए कमी-कुंजी विधि होने के लिए अनावश्यक है।

आप जितनी बार आवश्यक हो उतनी बार प्राथमिकता कतार में एक आइटम जोड़ सकते हैं और डुप्लिकेट को बाहर निकालने के लिए आपके द्वारा देखे जाने वाले नोड्स का ट्रैक रखें। पहली बार जब आप कतार से इसे पॉप करके एक नोड पर जाते हैं, तो आपको उस नोड का सबसे छोटा रास्ता मिल गया है और प्राथमिकता कतार पर इसकी सभी भविष्य की घटनाओं को अनदेखा कर सकता है।

प्राथमिकता कतार पर कई अतिरिक्त नोड्स होने से समस्या बहुत अधिक नहीं है क्योंकि यह O(log N) संरचना है। (आपको 1 मिलियन वस्तुओं के लिए 20 तुलना और 1 अरब वस्तुओं के लिए 30 तुलना करना है।)

संपादित करें: बाद में इस सवाल पर के बाद, मैं थोड़ा मेरा उत्तर से निराश हूं: उन चीजों के सभी कतार के बाहर आ गया है जब तक आप कुछ विशेष canipulations बाद में करना होगा। जीवन में कई चीजों की तरह, यह नीचे आता है कि आप अपनी याददाश्त और ऐसा करने से जुड़े लागतों का प्रबंधन कैसे करते हैं। लेकिन सामान्य बिंदु बनी हुई है: कमी-कुंजी आवश्यक है, भले ही यह वांछनीय हो।

+0

बाद में इस प्रश्न के बाद, मैं अपने उत्तर से थोड़ा निराश हूं: उन सभी चीजों को कतार से बाहर आना होगा जबतक कि आप बाद में कुछ विशेष कण नहीं करते। – Richard

+2

मुझे आश्चर्य है कि आप थोड़ा निराश हैं। वास्तविक अभ्यास में, "उन सभी चीजों" में इतने सारे नहीं होंगे कि प्रदर्शन उल्लेखनीय रूप से गिरावट आएगा। Http://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-using-priority_queue-stl/ पर एक अच्छा लेख है जो सी ++ एसटीएल का उपयोग करते समय केवल इस दृष्टिकोण को लेता है। –

+3

@ रिचर्ड यह एक व्यावहारिक समाधान है। हम इसे अपने आवेदन में कई स्थानों पर उपयोग करते हैं और हम एक अलग unordered_set बनाए रखते हैं जो नोड्स का दौरा करता है। जब आप प्रत्येक कुंजी डालने के लिए कम करने वाली चाबियों की जटिलताओं और ओवरहेड को देखते हैं तो आपका समाधान बेहतर होता है। – blueskin

0

यदि आप C++ stl make_heap()/pop_heap()/push_heap() का उपयोग कर रहे हैं, तो अंडरलाइन हेप वेक्टर में इंडेक्स से इंडेक्स में इंडेक्स रखने के लिए कोई तरीका नहीं है, मुझे लगता है कि आपको अपने हीप फ़ंक्शन को लागू करना चाहिए बढ़ने-कुंजी/घटाने-कुंजी ऑपरेशन में ओ (लॉगऑन) प्राप्त करने के लिए।

+0

ठीक है, लेकिन यह बदलती कुंजी को कम करने के बजाय बस एसटीएल का उपयोग करने के लिए संभव है। http://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-using-priority_queue-stl/ –

संबंधित मुद्दे