2012-05-23 15 views
9

में सबसे लंबे समय तक पथ एक DAG में सबसे लंबे समय तक पथ ढूंढने के लिए, मैं 2 एल्गोरिदम के बारे में पता कर रहा हूँ: algo 1: एक सांस्थितिकीय तरह कर + तरह के परिणाम पर गतिशील प्रोग्रामिंग का उपयोग ~ या ~ algo 2: गणना सभी डीएफएस का उपयोग डीएजी में पथ, और सबसे लंबे समय तक रिकॉर्ड। ऐसा लगता है कि डीएफएस के साथ सभी पथों को गिनती से बेहतर जटिलता है। क्या यह सच है?एक DAG

+0

[सीएस.एसई] पर संबंधित: [डीएजी में दो शीर्षकों के बीच सबसे कम और सबसे लंबे पथ ढूंढना] (http://cs.stackexchange.com/q/11295/11177) – Palec

उत्तर

8

आपका दूसरा विकल्प गलत है: डीएफएस, सभी संभव रास्तों का पता लगाने के नहीं है जब तक कि आपका ग्राफ एक पेड़ या एक जंगल है, और आप जड़ों से शुरू करते हैं। दूसरी एल्गोरिथ्म है कि मैं जानता हूँ कि वजन को नकारने जाता है और कम से कम पथ की खोज है, लेकिन यह top sort + DP algorithm कि आप # 1 के रूप में सूचीबद्ध की तुलना में कुछ धीमी है।

+0

ठीक है, मेरा मतलब डीएफएस से पुनरारंभ करना है किसी भी वर्टेक्स जिसे पिछले डीएफएस पास में नहीं देखा गया है। वह पूरे डीएजी का पता लगाएगा। क्या यह टॉपो सॉर्ट + डीपी से तेज नहीं होना चाहिए? vertexes है कि सभी रास्तों का पता लगाने नहीं होगा का दौरा नहीं किया गया से पुनः आरंभ करने के साथ – Frank

+0

@Frank डीएफएस। ग्राफ 'ए-> बी-> सी' पर विचार करें; आप बी से डीएफएस शुरू करते हैं, सी पर जाते हैं, और रोकते हैं; फिर ए से पुनरारंभ करें, बी पर जाएं, और फिर से रुकें, क्योंकि आपने पहले ही सी का दौरा किया है। डीएफएस मिले दोनों पथ, 'बी-सी' और 'ए-बी', लंबाई 1 के हैं; सबसे लंबा रास्ता 'ए-बी-सी' लंबाई 2 है। – dasblinkenlight

+0

आप बी से क्यों शुरू करेंगे? आपको स्रोतों से डीएफएस शुरू करना होगा। – Frank

3

की गणना एक 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 
+1

क्या आपने इस कोड में डबल-हीरा ग्राफ पास करने का प्रयास किया था? ऐसा लगता है कि इसमें सबसे लंबा रास्ता गुम होने का 50/50 मौका है। – dasblinkenlight

+0

मैंने अभी कोशिश की है: [[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

+0

मैंने आपके कोड में 'देखी गई' के उपयोग को गलत समझा: आपने इसे सेट किया है, लेकिन आप यह तय करने के लिए इसका उपयोग नहीं करते कि आपको ट्रैवर्सल जारी रखना चाहिए या नहीं। ऐसा नहीं है जिसे [डीएफएस] कहा जाता है (http://en.wikipedia.org/wiki/Depth-first_search), क्योंकि डीएफएस पूरी तरह से खोजे गए नोड्स पर नहीं जाता है। डीएफएस और आपके कोड के बीच सबसे बड़ा अंतर यह है कि आपका कोड बेहद अक्षम है। मेरा मतलब यह देखने के लिए एक ही हीरा पैटर्न को पचास बार दोहराने का प्रयास करें: आपका प्रोग्राम सभी '2^50' पथों का पता लगाएगा, और यह अन्वेषण करने के लिए बहुत सारे पथ हैं। – dasblinkenlight

2

नहीं डीएफएस की जरूरत है। एल्गोरिथ्म: एक 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 किनारों के भीतर उच्चतम ई जब सभी नोड्स संसाधित किए जा चुके है लेता है।

+0

यह सही जवाब है; https://en.wikipedia.org/wiki/Longest_path_problem#Acyclic_graphs_and_critical_paths देखें –