में सबसे लंबे समय तक पथ एक DAG में सबसे लंबे समय तक पथ ढूंढने के लिए, मैं 2 एल्गोरिदम के बारे में पता कर रहा हूँ: algo 1: एक सांस्थितिकीय तरह कर + तरह के परिणाम पर गतिशील प्रोग्रामिंग का उपयोग ~ या ~ algo 2: गणना सभी डीएफएस का उपयोग डीएजी में पथ, और सबसे लंबे समय तक रिकॉर्ड। ऐसा लगता है कि डीएफएस के साथ सभी पथों को गिनती से बेहतर जटिलता है। क्या यह सच है?एक DAG
एक DAG
उत्तर
आपका दूसरा विकल्प गलत है: डीएफएस, सभी संभव रास्तों का पता लगाने के नहीं है जब तक कि आपका ग्राफ एक पेड़ या एक जंगल है, और आप जड़ों से शुरू करते हैं। दूसरी एल्गोरिथ्म है कि मैं जानता हूँ कि वजन को नकारने जाता है और कम से कम पथ की खोज है, लेकिन यह top sort + DP algorithm कि आप # 1 के रूप में सूचीबद्ध की तुलना में कुछ धीमी है।
ठीक है, मेरा मतलब डीएफएस से पुनरारंभ करना है किसी भी वर्टेक्स जिसे पिछले डीएफएस पास में नहीं देखा गया है। वह पूरे डीएजी का पता लगाएगा। क्या यह टॉपो सॉर्ट + डीपी से तेज नहीं होना चाहिए? vertexes है कि सभी रास्तों का पता लगाने नहीं होगा का दौरा नहीं किया गया से पुनः आरंभ करने के साथ – Frank
@Frank डीएफएस। ग्राफ 'ए-> बी-> सी' पर विचार करें; आप बी से डीएफएस शुरू करते हैं, सी पर जाते हैं, और रोकते हैं; फिर ए से पुनरारंभ करें, बी पर जाएं, और फिर से रुकें, क्योंकि आपने पहले ही सी का दौरा किया है। डीएफएस मिले दोनों पथ, 'बी-सी' और 'ए-बी', लंबाई 1 के हैं; सबसे लंबा रास्ता 'ए-बी-सी' लंबाई 2 है। – dasblinkenlight
आप बी से क्यों शुरू करेंगे? आपको स्रोतों से डीएफएस शुरू करना होगा। – Frank
की गणना एक DAG के सारे रास्तों "डीएफएस" का उपयोग:
def enumerate_dag(g):
def enumerate_r(n, paths, visited, a_path = []):
a_path += [n]
visited[n] = 1
if not g[n]:
paths += [list(a_path)]
else:
for nn in g[n]:
enumerate_r(nn, paths, visited, list(a_path))
paths, N = [], len(g)
visited = np.zeros((N), dtype='int32')
for root in range(N):
if visited[root]: continue
enumerate_r(root, paths, visited, [])
return paths
क्या आपने इस कोड में डबल-हीरा ग्राफ पास करने का प्रयास किया था? ऐसा लगता है कि इसमें सबसे लंबा रास्ता गुम होने का 50/50 मौका है। – dasblinkenlight
मैंने अभी कोशिश की है: [[1,2], [3], [3], [4], [5,6], [7], [7], [8], [9], [ ]]। मुझे 4 पथ मिलते हैं: [[0, 1, 3, 4, 5, 7, 8, 9], [0, 1, 3, 4, 6, 7, 8, 9], [0, 2, 3, 4 , 5, 7, 8, 9], [0, 2, 3, 4, 6, 7, 8, 9]], जो मुझे विश्वास है कि सही जवाब है। जहां तक मैं कह सकता हूं (कई अन्य परीक्षणों से), यह एल्गोरिदम सही ढंग से एक डीएजी में पथों को दर्शाता है। टॉपो सॉर्ट डीएफएस के बहुत समान उपयोग पर आधारित है। बशर्ते आप स्रोतों पर प्रारंभ/पुनरारंभ करें, डीएफएस प्रत्येक स्रोत से पहुंचने योग्य * सभी * नोड्स का पता लगाएगा, इसलिए उपरोक्त कोड * पूरी तरह से * डीएजी की खोज करता है, कोई वर्टेक्स याद नहीं किया जाता है। – Frank
मैंने आपके कोड में 'देखी गई' के उपयोग को गलत समझा: आपने इसे सेट किया है, लेकिन आप यह तय करने के लिए इसका उपयोग नहीं करते कि आपको ट्रैवर्सल जारी रखना चाहिए या नहीं। ऐसा नहीं है जिसे [डीएफएस] कहा जाता है (http://en.wikipedia.org/wiki/Depth-first_search), क्योंकि डीएफएस पूरी तरह से खोजे गए नोड्स पर नहीं जाता है। डीएफएस और आपके कोड के बीच सबसे बड़ा अंतर यह है कि आपका कोड बेहद अक्षम है। मेरा मतलब यह देखने के लिए एक ही हीरा पैटर्न को पचास बार दोहराने का प्रयास करें: आपका प्रोग्राम सभी '2^50' पथों का पता लगाएगा, और यह अन्वेषण करने के लिए बहुत सारे पथ हैं। – dasblinkenlight
नहीं डीएफएस की जरूरत है। एल्गोरिथ्म: एक DAG जी प्रत्येक चाप एक चर ई रखती
for each node with no predecessor :
for each of his leaving arcs, E=1.
for each node whose predecessors have all been visited :
for each of his leaving arcs, E=max(E(entering arcs))+1.
MAX_PATH किनारों के भीतर उच्चतम ई जब सभी नोड्स संसाधित किए जा चुके है लेता है।
यह सही जवाब है; https://en.wikipedia.org/wiki/Longest_path_problem#Acyclic_graphs_and_critical_paths देखें –
[सीएस.एसई] पर संबंधित: [डीएजी में दो शीर्षकों के बीच सबसे कम और सबसे लंबे पथ ढूंढना] (http://cs.stackexchange.com/q/11295/11177) – Palec