क्या कोई मुझे बता सकता है कि एकल स्रोत के सबसे छोटे रास्ते के लिए डायक्स्ट्रा का एल्गोरिथ्म क्यों मानता है कि किनारों को गैर-नकारात्मक होना चाहिए।
मैं केवल किनारों के बारे में बात कर रहा हूं नकारात्मक वजन चक्र नहीं।
क्या कोई मुझे बता सकता है कि एकल स्रोत के सबसे छोटे रास्ते के लिए डायक्स्ट्रा का एल्गोरिथ्म क्यों मानता है कि किनारों को गैर-नकारात्मक होना चाहिए।
मैं केवल किनारों के बारे में बात कर रहा हूं नकारात्मक वजन चक्र नहीं।
जवाबों:
स्मरण करें कि दीजकस्ट्रा के एल्गोरिथ्म में, एक बार एक शीर्ष को "बंद" (और खुले सेट के बाहर) के रूप में चिह्नित किया गया है - एल्गोरिथ्म ने इसके लिए सबसे छोटा रास्ता ढूंढ लिया , और उसे इस नोड को फिर से विकसित नहीं करना पड़ेगा - यह इसके लिए विकसित पथ को मानता है। रास्ता सबसे छोटा है।
लेकिन नकारात्मक भार के साथ - यह सच नहीं हो सकता है। उदाहरण के लिए:
A
/ \
/ \
/ \
5 2
/ \
B--(-10)-->C
V={A,B,C} ; E = {(A,C,2), (A,B,5), (B,C,-10)}
ए से दिक्जस्त्र पहले सी विकसित होगा, और बाद में खोजने में विफल रहेगा A->B->C
थोड़ा गहरा स्पष्टीकरण संपादित करें :
ध्यान दें कि यह महत्वपूर्ण है, क्योंकि प्रत्येक छूट चरण में, एल्गोरिथ्म "लागत" को "बंद" नोड्स के लिए मानता है, वास्तव में न्यूनतम है, और इस प्रकार अगले चयनित होने वाले नोड भी न्यूनतम हैं।
इसका विचार यह है: यदि हमारे पास खुले में एक शिखर है जैसे कि इसकी लागत न्यूनतम है - किसी भी शीर्ष पर किसी भी सकारात्मक संख्या को जोड़कर - न्यूनतमता कभी नहीं बदलेगी।
सकारात्मक संख्याओं पर बाधा के बिना - उपरोक्त धारणा सत्य नहीं है।
चूँकि हम प्रत्येक शीर्ष को "जानते" हैं जो कि "बंद" था, न्यूनतम है - हम आराम से कदम उठा सकते हैं - बिना "पीछे देखे"। यदि हमें "पीछे मुड़कर" देखने की आवश्यकता है - तो बेलमैन-फोर्ड ऐसा करने के लिए एक पुनरावर्ती (डीपी) समाधान प्रदान करता है।
A->B
5 और A->C
2 करेंगे। फिर B->C
करेंगे -5
। तो बेलमैन-फोर्ड के समान मूल्य C
होगा -5
। यह कैसे सही जवाब नहीं दे रहा है?
A
0. के मान के साथ "बंद" नोड होगा, फिर, यह न्यूनतम मूल्यवान नोड पर दिखेगा, B
5 है और C
2. न्यूनतम है C
, इसलिए यह C
मान 2 के साथ बंद होगा और कभी भी पीछे नहीं दिखेगा, जब बाद B
में बंद कर दिया गया है, यह C
पहले से ही "बंद" होने के बाद से इसके मूल्य को संशोधित नहीं कर सकता है।
A -> B -> C
? यह पहले C
2 की दूरी को अपडेट करेगा , और फिर B
5. की दूरी को मान लेगा कि आपके ग्राफ में कोई आउटगोइंग एज नहीं है C
, तब हम कुछ भी नहीं करते हैं जब विजिटिंग C
(और इसकी दूरी अभी भी 2 है)। तब हम D
आसन्न नोड्स पर जाते हैं, और एकमात्र आसन्न नोड है C
, जिसकी नई दूरी -5 है। ध्यान दें कि दिज्कस्ट्रा के एल्गोरिथ्म में, हम उस अभिभावक पर भी नज़र रखते हैं, जहाँ से हम नोड तक पहुँचते हैं (और अपडेट करते हैं), और इसे करने से C
, आपको अभिभावक मिलेंगे B
, और फिर A
एक सही परिणाम मिलेगा । मैं क्या खो रहा हूँ?
जब मैं अपनी व्याख्या में डीजकस्ट्रा के एल्गोरिथ्म का उल्लेख करता हूं, तो मैं डीजेकस्ट्रा के एल्गोरिथ्म के बारे में बात करूंगा
इसलिए शुरू में मानों ( स्रोत से शिखर तक की दूरी ) को शुरू में प्रत्येक शीर्ष पर सौंपा गया है,
हम सबसे पहले क्यू = [ए, बी, सी] में वर्टेक्स निकालते हैं जिसका सबसे छोटा मूल्य है, यानी ए, जिसके बाद क्यू = [बी, सी] । नोट A में B और C के लिए एक निर्देशित धार है, दोनों ही Q में हैं, इसलिए हम उन दोनों मानों को अपडेट करते हैं,
अब हम C को (2 <5) के रूप में निकालते हैं, अब Q = [B] । ध्यान दें कि C कुछ भी नहीं से जुड़ा है, इसलिए line16
लूप नहीं चलता है।
अंत में हम बी निकालते हैं, जिसके बाद । नोट B में C के लिए एक निर्देशित बढ़त है, लेकिन C Q में मौजूद नहीं है इसलिए हम फिर से लूप में प्रवेश नहीं करते हैं line16
,
इसलिए हम दूरी के साथ समाप्त होते हैं
ध्यान दें कि जब आप जाते हैं तो यह A से C की सबसे छोटी दूरी 5 + -10 = -5 है, तो यह गलत है ।
तो इस ग्राफ के लिए दिज्क्स्ट्रा का एल्गोरिथम गलत तरीके से A से C की दूरी की गणना करता है।
ऐसा इसलिए होता है क्योंकि डेज़्क्स्ट्रा के एल्गोरिथ्म में कोने से पहले से निकाले गए कोने तक एक छोटा रास्ता खोजने की कोशिश नहीं की जाती है ।
क्या line16
पाश कर रही है शिखर ले रहा है यू और कह रही है "हे लगता है कि हम पर जा सकते हैं वी के माध्यम से स्रोत से यू , कि (आल्ट या वैकल्पिक) दूरी किसी भी वर्तमान की तुलना में बेहतर है जिले [V] हम मिल गया? तो अद्यतन की सुविधा देता है, तो डिस्ट [v] "
ध्यान दें कि line16
वे सभी पड़ोसियों की जाँच करते हैं v (यानी एक निर्देशित किनारा u से v तक मौजूद है ), u की जो अभी भी Q में हैं । में line14
वे प्र तो से दौरा नोट निकल यदि एक्स के एक दौरा पड़ोसी है यू , पथ है भी नहीं माना करने के लिए स्रोत से एक संभव कम तरीके के रूप में वी ।
ऊपर हमारे उदाहरण में, C, B का एक पड़ोसी था, इस प्रकार पथ पर विचार नहीं किया गया था, जिससे वर्तमान सबसे छोटा मार्ग अपरिवर्तित था।
यह वास्तव में उपयोगी है अगर बढ़त वजन सभी सकारात्मक नंबर दिए गए हैं तो हम अपने समय पर विचार रास्तों कि बर्बाद नहीं करेंगे क्योंकि, नहीं किया जा सकता कम।
तो मैं कहता हूं कि जब इस एल्गोरिथ्म को चलाने के लिए यदि 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 का कोई पड़ोसी नहीं है। लंबाई (ए, बी) कोने के बीच की लंबाई है ए और बी।
दिज्क्स्ट्रा का एल्गोरिथम मानता है कि पथ केवल 'भारी' बन सकते हैं, ताकि यदि आपके पास A से B तक का मार्ग 3 के वजन के साथ है, और A के C से 3 के वजन वाला मार्ग है, तो कोई रास्ता नहीं है जिससे आप एक किनारे जोड़ सकते हैं 3 से कम वजन वाले A से B तक C के माध्यम से प्राप्त करें।
यह धारणा एल्गोरिदम की तुलना में एल्गोरिथ्म को तेज बनाती है जिसे नकारात्मक भार को ध्यान में रखना पड़ता है।
दिज्क्स्ट्रा के एल्गोरिथ्म की शुद्धता:
एल्गोरिथ्म के किसी भी चरण में हमारे पास 2 सेट हैं। सेट ए में वे कोने शामिल हैं जिनसे हमने सबसे छोटे रास्तों की गणना की है। सेट बी में शेष कोने शामिल हैं।
आगमनात्मक परिकल्पना : प्रत्येक चरण में हम यह मानेंगे कि पिछले सभी पुनरावृत्तियाँ सही हैं।
आगमनात्मक कदम : जब हम सेट A में एक वर्टेक्स V जोड़ते हैं और डिस्टर्ब होने के लिए दूरी तय करते हैं [V], तो हमें यह साबित करना होगा कि यह दूरी इष्टतम है। यदि यह इष्टतम नहीं है, तो वर्टेक्स V के लिए कुछ और रास्ता होना चाहिए जो कि छोटी लंबाई का हो।
मान लीजिए कि यह कोई और मार्ग किसी शीर्ष X से होकर जाता है।
अब, चूंकि डिस्ट [V] <= dist [X] है, इसलिए V का कोई भी दूसरा रास्ता, दूरी [V] की लंबाई तक कम से कम होगा, जब तक कि ग्राफ में नकारात्मक किनारे की लंबाई न हो।
इस प्रकार काम करने के लिए dijkstra के एल्गोरिथ्म के लिए, किनारे का वजन गैर नकारात्मक होना चाहिए।
निम्न ग्राफ पर दीजकस्ट्रा के एल्गोरिथ्म का प्रयास करें, यह मानते हुए A
कि स्रोत नोड है, क्या हो रहा है:
A->B
इच्छा 1
और A->C
इच्छा 100
। फिर B->D
करेंगे 2
। फिर C->D
करेंगे -4900
। तो बेलमैन-फोर्ड के समान मूल्य D
होगा -4900
। यह कैसे सही जवाब नहीं दे रहा है?
A->B
होगा 1
और A->C
होगा 100
। फिर B
पता लगाया जाता है और सेट किया B->D
जाता है 2
। तब डी की खोज की जाती है क्योंकि वर्तमान में इसका स्रोत सबसे छोटा रास्ता है? मैं कह रही है कि अगर में सही होगा B->D
था 100
, C
होगा पहले पता लगाया गया है? मैं समझता हूं कि आपके अलावा अन्य सभी उदाहरण लोग देते हैं।
स्मरण करें कि दिज्क्स्ट्रा के एल्गोरिथ्म में, एक बार एक शीर्ष को "बंद" (और खुले सेट के बाहर) के रूप में चिह्नित किया जाता है - यह मानता है कि इससे उत्पन्न होने वाले किसी भी नोड को अधिक दूरी तक ले जाना होगा , इसलिए एल्गोरिथ्म ने इसे सबसे छोटा पथ पाया, और होगा इस नोड को फिर से विकसित नहीं करना है, लेकिन यह नकारात्मक भार के मामले में सही नहीं है।
अब तक के अन्य उत्तर बहुत अच्छी तरह से प्रदर्शित करते हैं कि क्यों दिज्क्स्ट्रा का एल्गोरिथ्म रास्तों पर नकारात्मक भार को संभाल नहीं सकता है।
लेकिन सवाल ही शायद रास्तों के वजन की गलत समझ पर आधारित है। यदि रास्तों पर नकारात्मक भार को सामान्य रूप से पथप्रदर्शक एल्गोरिदम में अनुमति दी जाएगी, तो आपको स्थायी लूप मिलेंगे जो बंद नहीं होंगे।
इस पर विचार करो:
A <- 5 -> B <- (-1) -> C <- 5 -> D
A और D के बीच इष्टतम पथ क्या है?
किसी भी पाथफाइंडिंग एल्गोरिदम को बी और सी के बीच लगातार लूप करना होगा क्योंकि ऐसा करने से कुल पथ का वजन कम हो जाएगा। तो एक कनेक्शन के लिए नकारात्मक भार की अनुमति देना किसी भी पथप्रदर्शक एल्गोरिथ्म मूट को प्रस्तुत करेगा, शायद सिवाय इसके कि यदि आप प्रत्येक कनेक्शन को केवल एक बार उपयोग करने के लिए सीमित करते हैं।
आप नकारात्मक चक्रों के साथ dijkstra के एल्गोरिथ्म का उपयोग कर सकते हैं, जिसमें नकारात्मक चक्र शामिल नहीं है, लेकिन आपको अनुमति देना चाहिए कि किसी शीर्ष को कई बार विज़िट किया जा सकता है और यह संस्करण खो देगा यह फास्ट टाइम जटिलता है।
उस मामले में व्यावहारिक रूप से मैंने देखा है कि एसपीएफए एल्गोरिदम का उपयोग करना बेहतर है, जिसमें सामान्य कतार होती है और नकारात्मक किनारों को संभाल सकती है।