डायजेक्ट्रा का एल्गोरिथ्म नकारात्मक भार किनारों के लिए क्यों काम नहीं करता है?


121

क्या कोई मुझे बता सकता है कि एकल स्रोत के सबसे छोटे रास्ते के लिए डायक्स्ट्रा का एल्गोरिथ्म क्यों मानता है कि किनारों को गैर-नकारात्मक होना चाहिए।

मैं केवल किनारों के बारे में बात कर रहा हूं नकारात्मक वजन चक्र नहीं।


3
एक अच्छे उदाहरण के साथ एक सही उत्तर होगा: stackoverflow.com/questions/6799172/…
— अमितक

जवाबों:


175

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

लेकिन नकारात्मक भार के साथ - यह सच नहीं हो सकता है। उदाहरण के लिए:

       A
      / \
     /   \
    /     \
   5       2
  /         \
  B--(-10)-->C

V={A,B,C} ; E = {(A,C,2), (A,B,5), (B,C,-10)}

ए से दिक्जस्त्र पहले सी विकसित होगा, और बाद में खोजने में विफल रहेगा A->B->C


थोड़ा गहरा स्पष्टीकरण संपादित करें :

ध्यान दें कि यह महत्वपूर्ण है, क्योंकि प्रत्येक छूट चरण में, एल्गोरिथ्म "लागत" को "बंद" नोड्स के लिए मानता है, वास्तव में न्यूनतम है, और इस प्रकार अगले चयनित होने वाले नोड भी न्यूनतम हैं।

इसका विचार यह है: यदि हमारे पास खुले में एक शिखर है जैसे कि इसकी लागत न्यूनतम है - किसी भी शीर्ष पर किसी भी सकारात्मक संख्या को जोड़कर - न्यूनतमता कभी नहीं बदलेगी।
सकारात्मक संख्याओं पर बाधा के बिना - उपरोक्त धारणा सत्य नहीं है।

चूँकि हम प्रत्येक शीर्ष को "जानते" हैं जो कि "बंद" था, न्यूनतम है - हम आराम से कदम उठा सकते हैं - बिना "पीछे देखे"। यदि हमें "पीछे मुड़कर" देखने की आवश्यकता है - तो बेलमैन-फोर्ड ऐसा करने के लिए एक पुनरावर्ती (डीपी) समाधान प्रदान करता है।


5
क्षमा करें, लेकिन मुझे कोई त्रुटि नहीं मिल रही है। पहले A->B5 और A->C2 करेंगे। फिर B->Cकरेंगे -5। तो बेलमैन-फोर्ड के समान मूल्य Cहोगा -5। यह कैसे सही जवाब नहीं दे रहा है?
— अनिर्बान नाग 'टिनटिनम'

5
@tintinmj सबसे पहले, दिक्जस्त्र A0. के मान के साथ "बंद" नोड होगा, फिर, यह न्यूनतम मूल्यवान नोड पर दिखेगा, B5 है और C2. न्यूनतम है C, इसलिए यह Cमान 2 के साथ बंद होगा और कभी भी पीछे नहीं दिखेगा, जब बाद Bमें बंद कर दिया गया है, यह Cपहले से ही "बंद" होने के बाद से इसके मूल्य को संशोधित नहीं कर सकता है।
— अमित

4
@amit दिज्क्स्ट्रा के एल्गोरिथ्म में रास्ता कैसे नहीं मिलेगा A -> B -> C? यह पहले C2 की दूरी को अपडेट करेगा , और फिर B5. की दूरी को मान लेगा कि आपके ग्राफ में कोई आउटगोइंग एज नहीं है C, तब हम कुछ भी नहीं करते हैं जब विजिटिंग C(और इसकी दूरी अभी भी 2 है)। तब हम Dआसन्न नोड्स पर जाते हैं, और एकमात्र आसन्न नोड है C, जिसकी नई दूरी -5 है। ध्यान दें कि दिज्कस्ट्रा के एल्गोरिथ्म में, हम उस अभिभावक पर भी नज़र रखते हैं, जहाँ से हम नोड तक पहुँचते हैं (और अपडेट करते हैं), और इसे करने से C, आपको अभिभावक मिलेंगे B, और फिर Aएक सही परिणाम मिलेगा । मैं क्या खो रहा हूँ?
— सुबह

12
@amit आपके तर्क के बारे में समस्या (मुझे लगता है), और मैंने अन्य लोगों को ऐसा करते हुए देखा है (अजीब तरह से), यह है कि आपको लगता है कि एल्गोरिथ्म नोड्स पर पुनर्विचार नहीं करेगा, जिनकी सबसे कम दूरी पहले से निर्धारित की गई है (और हम जो कर रहे हैं), लेकिन यह सही नहीं है, और यही कारण है कि हमारे पास "विश्राम" कदम है ... हम ग्राफ के सभी नोड्स के माध्यम से पुनरावृत्ति करते हैं, और, उनमें से प्रत्येक के लिए, हम आसन्न नोड्स के माध्यम से पुनरावृत्ति करते हैं, भले ही आसन्न नोड में से कोई भी हो। उदाहरण के लिए, हमारी न्यूनतम प्राथमिकता वाली कतार से पहले ही हटा दिए गए हैं।
— 15:15 बजे nbro

10
@amit एक समान प्रश्न के लिए इस उत्तर को जांचें, जहां उदाहरण वास्तव में समझ में आता है: stackoverflow.com/a/6799344/3924118
— nbro

37

स्रोत के साथ नीचे दिखाए गए ग्राफ पर विचार करें जैसा कि वर्टेक्स ए। पहले डिक्स्ट्रा के एल्गोरिदम को स्वयं चलाने की कोशिश करें।

यहां छवि विवरण दर्ज करें

जब मैं अपनी व्याख्या में डीजकस्ट्रा के एल्गोरिथ्म का उल्लेख करता हूं, तो मैं डीजेकस्ट्रा के एल्गोरिथ्म के बारे में बात करूंगा

दीजकस्ट्रा का एल्गोरिदम

इसलिए शुरू में मानों ( स्रोत से शिखर तक की दूरी ) को शुरू में प्रत्येक शीर्ष पर सौंपा गया है,

प्रारंभ

हम सबसे पहले क्यू = [ए, बी, सी] में वर्टेक्स निकालते हैं जिसका सबसे छोटा मूल्य है, यानी ए, जिसके बाद क्यू = [बी, सी] । नोट A में B और C के लिए एक निर्देशित धार है, दोनों ही Q में हैं, इसलिए हम उन दोनों मानों को अपडेट करते हैं,

पहला पुनरावृत्ति

अब हम C को (2 <5) के रूप में निकालते हैं, अब Q = [B] । ध्यान दें कि C कुछ भी नहीं से जुड़ा है, इसलिए line16लूप नहीं चलता है।

दूसरा पुनरावृत्ति

अंत में हम बी निकालते हैं, जिसके बाद क्यू फी है। नोट B में C के लिए एक निर्देशित बढ़त है, लेकिन C Q में मौजूद नहीं है इसलिए हम फिर से लूप में प्रवेश नहीं करते हैं line16,

3?

इसलिए हम दूरी के साथ समाप्त होते हैं

कोई बदलाव नहीं

ध्यान दें कि जब आप जाते हैं तो यह A से C की सबसे छोटी दूरी 5 + -10 = -5 है, तो यह गलत है a से b तक c।

तो इस ग्राफ के लिए दिज्क्स्ट्रा का एल्गोरिथम गलत तरीके से A से C की दूरी की गणना करता है।

ऐसा इसलिए होता है क्योंकि डेज़्क्स्ट्रा के एल्गोरिथ्म में कोने से पहले से निकाले गए कोने तक एक छोटा रास्ता खोजने की कोशिश नहीं की जाती है ।

क्या line16पाश कर रही है शिखर ले रहा है यू और कह रही है "हे लगता है कि हम पर जा सकते हैं वी के माध्यम से स्रोत से यू , कि (आल्ट या वैकल्पिक) दूरी किसी भी वर्तमान की तुलना में बेहतर है जिले [V] हम मिल गया? तो अद्यतन की सुविधा देता है, तो डिस्ट [v] "

ध्यान दें कि line16वे सभी पड़ोसियों की जाँच करते हैं v (यानी एक निर्देशित किनारा u से v तक मौजूद है ), u की जो अभी भी Q में हैं । में line14वे प्र तो से दौरा नोट निकल यदि एक्स के एक दौरा पड़ोसी है यू , पथ सोर्स टू यू टू एक्सहै भी नहीं माना करने के लिए स्रोत से एक संभव कम तरीके के रूप में वी ।

ऊपर हमारे उदाहरण में, C, B का एक पड़ोसी था, इस प्रकार पथ ए से बी तक सीपर विचार नहीं किया गया था, जिससे वर्तमान सबसे छोटा मार्ग A से Cअपरिवर्तित था।

यह वास्तव में उपयोगी है अगर बढ़त वजन सभी सकारात्मक नंबर दिए गए हैं तो हम अपने समय पर विचार रास्तों कि बर्बाद नहीं करेंगे क्योंकि, नहीं किया जा सकता कम।

तो मैं कहता हूं कि जब इस एल्गोरिथ्म को चलाने के लिए यदि x को y से पहले Q से निकाला जाता है , तो इसका एक रास्ता खोजना संभव नहीं है - संभव नहींजो छोटा है। इसे एक उदाहरण से समझाता हूं,

जैसा कि y को अभी निकाला गया है और x को पहले ही निकाला गया था, तब dist [y]> dist [x] क्योंकि अन्यथा x से पहले y को निकाला जाता था । ( न्यूनतम दूरी पहले)line 13

और जैसा कि हमने पहले ही मान लिया था कि किनारे का वज़न सकारात्मक है, यानी लंबाई (x, y)> 0 । अतः y के माध्यम से वैकल्पिक दूरी (alt) हमेशा अधिक से अधिक होना निश्चित है, यानी dist [y] + लंबाई (x, y)> dist / x] । तो dist के मान [x] को अपडेट नहीं किया जाता, भले ही y को x का मार्ग माना जाता था , इस प्रकार हम यह निष्कर्ष निकालते हैं कि यह केवल y के पड़ोसियों पर विचार करने के लिए समझ में आता है जो अभी भी Q में हैं (टिप्पणी करें line16)

लेकिन यह बात सकारात्मक बढ़त की लंबाई की हमारी धारणा पर टिका है, अगर लंबाई (यू, वी) <0 तो इस बात पर निर्भर करता है कि हम उस नकारात्मक कोण को कैसे बदल सकते हैं, जो तुलना में होने के बाद डिस्ट [x] को बदल सकता है line18।

तो कोई भी गड़बड़ी [x] हमारे द्वारा की गई गणना गलत होगी यदि x को सभी वर्टिस v से पहले हटा दिया जाता है - जैसे कि x , v से पड़ोसी है जो उन्हें जोड़ने वाले नकारात्मक किनारे से हटा दिया गया है।

क्योंकि उनमें से प्रत्येक v कोने में स्रोत से x तक संभावित "बेहतर" पथ पर दूसरा अंतिम शीर्ष है , जो कि दिक्जस्ट्रा के एल्गोरिथ्म द्वारा खारिज कर दिया गया है।

इसलिए मैंने ऊपर दिए उदाहरण में, गलती इसलिए थी क्योंकि B को हटाए जाने से पहले C को हटा दिया गया था। जबकि वह C एक नकारात्मक बढ़त के साथ B का पड़ोसी था!

बस स्पष्ट करने के लिए, बी और सी ए के पड़ोसी हैं। B का एक ही पड़ोसी C है और C का कोई पड़ोसी नहीं है। लंबाई (ए, बी) कोने के बीच की लंबाई है ए और बी।


2
जैसा आपने कहा, इसे हल करने का बेहतर तरीका यह है कि प्रत्येक तुलना के बाद heapq.heappush पद्धति का उपयोग किया जाए। हम कतार में अद्यतन दूरी को पीछे धकेलते हैं। इस स्थिति के तहत, दिक्जिस्ट्रा नकारात्मक भार पर काम कर सकता है। मैंने कोशिश की, और परिणाम 0,5, -5
— नोसेंस

1
"एक्स टू यू का पथ स्रोत भी नहीं माना जाता है"; क्या आपका मतलब यू टू एक्स से है?
— slmatrix

1
@slmatrix उस पकड़ने के लिए धन्यवाद, हाँ, मेरा मतलब था कि स्रोत से यू तक का रास्ता, क्योंकि x यू का पड़ोसी है।
— आदित्य पी

23

दिज्क्स्ट्रा का एल्गोरिथम मानता है कि पथ केवल 'भारी' बन सकते हैं, ताकि यदि आपके पास A से B तक का मार्ग 3 के वजन के साथ है, और A के C से 3 के वजन वाला मार्ग है, तो कोई रास्ता नहीं है जिससे आप एक किनारे जोड़ सकते हैं 3 से कम वजन वाले A से B तक C के माध्यम से प्राप्त करें।

यह धारणा एल्गोरिदम की तुलना में एल्गोरिथ्म को तेज बनाती है जिसे नकारात्मक भार को ध्यान में रखना पड़ता है।


8

दिज्क्स्ट्रा के एल्गोरिथ्म की शुद्धता:

एल्गोरिथ्म के किसी भी चरण में हमारे पास 2 सेट हैं। सेट ए में वे कोने शामिल हैं जिनसे हमने सबसे छोटे रास्तों की गणना की है। सेट बी में शेष कोने शामिल हैं।

आगमनात्मक परिकल्पना : प्रत्येक चरण में हम यह मानेंगे कि पिछले सभी पुनरावृत्तियाँ सही हैं।

आगमनात्मक कदम : जब हम सेट A में एक वर्टेक्स V जोड़ते हैं और डिस्टर्ब होने के लिए दूरी तय करते हैं [V], तो हमें यह साबित करना होगा कि यह दूरी इष्टतम है। यदि यह इष्टतम नहीं है, तो वर्टेक्स V के लिए कुछ और रास्ता होना चाहिए जो कि छोटी लंबाई का हो।

मान लीजिए कि यह कोई और मार्ग किसी शीर्ष X से होकर जाता है।

अब, चूंकि डिस्ट [V] <= dist [X] है, इसलिए V का कोई भी दूसरा रास्ता, दूरी [V] की लंबाई तक कम से कम होगा, जब तक कि ग्राफ में नकारात्मक किनारे की लंबाई न हो।

इस प्रकार काम करने के लिए dijkstra के एल्गोरिथ्म के लिए, किनारे का वजन गैर नकारात्मक होना चाहिए।


6

निम्न ग्राफ पर दीजकस्ट्रा के एल्गोरिथ्म का प्रयास करें, यह मानते हुए Aकि स्रोत नोड है, क्या हो रहा है:

ग्राफ़


6
क्षमा करें, लेकिन मुझे कोई त्रुटि नहीं मिल रही है। पहले A->Bइच्छा 1और A->Cइच्छा 100। फिर B->Dकरेंगे 2। फिर C->Dकरेंगे -4900। तो बेलमैन-फोर्ड के समान मूल्य Dहोगा -4900। यह कैसे सही जवाब नहीं दे रहा है?
— अनिर्बान नाग 'टिनटिनम'

9
@tintinmj यदि आपके पास D से एक आउटगोइंग एज है, तो D की दूरी कम होने से पहले यह विज़िट कर लेगा और इसलिए यह अपडेट नहीं है। इसके बाद निश्चित रूप से त्रुटि होगी। यदि आप D के 2 को आउटगोइंग किनारों को स्कैन करने के बाद पहले से ही अंतिम दूरी मानते हैं, तो भी इस ग्राफ़ में त्रुटि होती है।
— क्रिश्चियन स्चनोरस

@ tb- इतने लम्बे समय के बाद पूछने के लिए क्षमा करें, लेकिन क्या मैं यहाँ सही रास्ते पर हूँ? पहले A->Bहोगा 1और A->Cहोगा 100। फिर Bपता लगाया जाता है और सेट किया B->Dजाता है 2। तब डी की खोज की जाती है क्योंकि वर्तमान में इसका स्रोत सबसे छोटा रास्ता है? मैं कह रही है कि अगर में सही होगा B->Dथा 100, Cहोगा पहले पता लगाया गया है? मैं समझता हूं कि आपके अलावा अन्य सभी उदाहरण लोग देते हैं।
— पेजमैन पोह

@PejmanPoh मेरी समझ से, यदि B-> D 100 था, चूंकि A-> C का उच्च स्तर HeapStructure में है, जिसका उपयोग किया जाएगा, तो निकालने का मिनट A-> C पहले आएगा, जिसका अर्थ है कि अगला पाया गया सबसे छोटा रास्ता पथ होगा C, उसके बाद C-> D जो कि वजन -5000 के साथ है, वह स्पष्ट विकल्प होगा, जिससे हम इस निष्कर्ष पर पहुंचेंगे कि सबसे छोटा रास्ता A-> C-> D से होगा और मुझे इस पर पूरा यकीन है सामान्य व्यवहार करो। इसलिए कभी-कभी जब हमारे पास नकारात्मक चक्र होते हैं, तब भी हमें सबसे छोटे रास्ते का सही मूल्य मिल सकता है, लेकिन निश्चित रूप से हमेशा नहीं, यह एक उदाहरण है जहां हम नहीं करेंगे ..
— T.Dimitrov

1

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


0

अब तक के अन्य उत्तर बहुत अच्छी तरह से प्रदर्शित करते हैं कि क्यों दिज्क्स्ट्रा का एल्गोरिथ्म रास्तों पर नकारात्मक भार को संभाल नहीं सकता है।

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

इस पर विचार करो:

A  <- 5 ->  B  <- (-1) ->  C <- 5 -> D

A और D के बीच इष्टतम पथ क्या है?

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


0

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

उस मामले में व्यावहारिक रूप से मैंने देखा है कि एसपीएफए ​​एल्गोरिदम का उपयोग करना बेहतर है, जिसमें सामान्य कतार होती है और नकारात्मक किनारों को संभाल सकती है।

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