2010-11-23 28 views
10

में सबसे लंबी पथ समस्या के लिए अनुकूलन चक्रीय ग्राफ में सबसे लंबा रास्ता खोजने की कोशिश करने के लिए कौन से अनुकूलन मौजूद हैं?चक्रीय ग्राफ

चक्रीय ग्राफ में सबसे लंबा रास्ता एनपी-पूर्ण माना जाता है। क्या ऑप्टिमाइज़ेशन या हेरिस्टिक्स पूरे ग्राफ को डीएफएसिंग से सबसे लंबा रास्ता तेज कर सकता है? क्या कोई संभाव्य दृष्टिकोण है?

मेरे पास विशिष्ट गुणों वाला ग्राफ है, लेकिन मैं सामान्य मामले में इसका उत्तर ढूंढ रहा हूं। कागजात से जुड़ा होना शानदार होगा। यहां आंशिक उत्तर दिया गया है:

  1. पुष्टि करें कि यह चक्रीय है। गतिशील प्रोग्रामिंग का उपयोग करके विश्वकोश ग्राफ में सबसे लंबा रास्ता आसानी से गणना की जाती है।

  2. पता लगाएं कि ग्राफ प्लानर है (कौन सा एल्गोरिदम सर्वोत्तम है?)। यदि ऐसा है, तो आप देख सकते हैं कि यह एक ब्लॉक ग्राफ, टॉलेमेमिक ग्राफ, या कैक्टि ग्राफ है और this paper में पाए गए तरीकों को लागू करें।

  3. पता लगाएं कि Donald B Johnson's algorithm (Java implementation) का उपयोग करके कितने सरल चक्र हैं। आप एक सरल चक्र में किनारे को हटाकर किसी भी चक्रीय ग्राफ को एक विश्वकोश में बदल सकते हैं। फिर आप the Wikipedia page पर पाए गए गतिशील प्रोग्रामिंग समाधान को चला सकते हैं। पूर्णता के लिए, आपको प्रत्येक चक्र के लिए यह एन बार करना होगा, जहां एन चक्र की लंबाई है। इस प्रकार, पूरे ग्राफ के लिए, आपको डीपी समाधान चलाने के लिए कितनी बार सभी चक्रों की लंबाई के उत्पाद के बराबर है।

  4. यदि आपको पूरे ग्राफ को डीएफएस करना है, तो आप प्रत्येक नोड की "पहुंच क्षमता" की गणना करके कुछ पथों को पूर्ववत कर सकते हैं। यह पहुंच क्षमता, जो मुख्य रूप से निर्देशित ग्राफ पर लागू होती है, नोड्स की संख्या प्रत्येक नोड पुनरावृत्ति के बिना पहुंच सकती है। यह संभवतः उस नोड से सबसे लंबा रास्ता हो सकता है। इस जानकारी के साथ, यदि आपका वर्तमान पथ प्लस नोड की पहुंचने योग्यता सबसे लंबे समय से कम है, तो उस शाखा को लेने में कोई बात नहीं है क्योंकि यह असंभव है कि आपको लंबा रास्ता मिल जाएगा।

+0

करता है (3 (कृपया, निश्चित-आकार सरणियों का उपयोग कर के बारे में कोई टिप्पणी नहीं। एक वास्तविक कार्यक्रम में सी ++ vector<int>) का उपयोग करें malloc() (या बेहतर अभी तक,। मैं सिर्फ यह इस तरह से तो बातें स्पष्ट हो जाएगा। लिखा था)) दृढ़ता से जुड़े घटकों को खोजने से संबंधित है? (http://en.wikipedia.org/wiki/Strongly_connected_component) - यदि नहीं, तो मैंने सोचा होगा कि आप उन लोगों के साथ कुछ कर सकते हैं। मैंने टार्ज़न्स एल्गोरिदम को समझने में काफी आसान पाया। – Steve314

+0

मैं ईमानदारी से नहीं देखता कि दृढ़ता से जुड़े घटकों या कशेरुक संकुचन की पहचान एलपीपी को हल करने में कैसे मदद करती है, लेकिन मैं गलत हो सकता हूं। इसे एक विश्वकोश ग्राफ में जोड़ने के लिए, मेरा मानना ​​है कि आपको सरल चक्र (जॉनसन) की आवश्यकता है, क्योंकि दृढ़ता से जुड़े घटकों में चक्र अभी भी हो सकते हैं। –

+0

शायद यह मदद नहीं करता है। मेरा विचार था कि एससीसी आमतौर पर पूरे ग्राफ से छोटे होते हैं, इसलिए प्रत्येक प्रविष्टि/निकास जोड़ी के लिए उनके माध्यम से सबसे लंबे मार्गों को ढूंढना अपेक्षाकृत तेज़ होना चाहिए। एससीसी को हटाएं और इनमें से प्रत्येक सबसे लंबे मार्ग-मार्ग-एससीसी समाधानों के लिए एक भारित किनारा जोड़ें और आपको एक विश्वकोशिक डिग्राफ के साथ समाप्त होना चाहिए जिसे आप गतिशील प्रोग्रामिंग कर सकते हैं। प्रत्येक सबसे लंबा मार्ग-दर-एससीसी एज वास्तव में उस किनारे को प्रतिस्थापित करता है जो एससीसी में प्रवेश करता है और किनारे को छोड़ देता है, साथ ही एससीसी के माध्यम से मार्ग भी जाता है। हालांकि, मुझे कुछ याद आ रहा है। – Steve314

उत्तर

4

यहाँ एक O (n * 2^n) गतिशील प्रोग्रामिंग दृष्टिकोण है कि संभव 20 कोने कहने के लिए होना चाहिए:

m(b, U) = b में समाप्त होने और केवल पर जाकर किसी भी पथ की अधिकतम लंबाई (कुछ) U में शिखर।

प्रारंभ में, m(b, {b}) = 0 सेट करें।

फिर, m(b, U) = अधिकतम U ऐसी है कि x में सभी x से अधिक m(x, U - x) + d(x, b) का मूल्य b और एक बढ़त (x, b) मौजूद नहीं है। U = V (शीर्षकों का पूरा सेट) के साथ, इन सभी मानों को अधिकतम अंतराल b के लिए लें। यह किसी भी पथ की अधिकतम लंबाई होगी।

निम्नलिखित सी कोड d[N][N] में दूरी मैट्रिक्स मानता है। यदि आपका ग्राफ़ असीमित है, तो आप इस सरणी में निरंतर 1 पर प्रत्येक पढ़ने की पहुंच को बदल सकते हैं। एक ट्रेसबैक जो अक्षरों का इष्टतम अनुक्रम दिखाता है (एक से अधिक हो सकता है) सरणी p[N][NBITS] में भी गणना की जाती है।

#define N 20 
#define NBITS (1 << N) 

int d[N][N];  /* Assumed to be populated earlier. -1 means "no edge". */ 
int m[N][NBITS]; /* DP matrix. -2 means "unknown". */ 
int p[N][NBITS]; /* DP predecessor traceback matrix. */ 

/* Maximum distance for a path ending at vertex b, visiting only 
    vertices in visited. */ 
int subsolve(int b, unsigned visited) { 
    if (visited == (1 << b)) { 
     /* A single vertex */ 
     p[b][visited] = -1; 
     return 0; 
    } 

    if (m[b][visited] == -2) { 
     /* Haven't solved this subproblem yet */ 
     int best = -1, bestPred = -1; 
     unsigned i; 
     for (i = 0; i < N; ++i) { 
      if (i != b && ((visited >> i) & 1) && d[i][b] != -1) { 
       int x = subsolve(i, visited & ~(1 << b)); 
       if (x != -1) { 
        x += d[i][b]; 
        if (x > best) { 
         best = x; 
         bestPred = i; 
        } 
       } 
      } 
     } 

     m[b][visited] = best; 
     p[b][visited] = bestPred; 
    } 

    return m[b][visited]; 
} 

/* Maximum path length for d[][]. 
    n must be <= N. 
    *last will contain the last vertex in the path; use p[][] to trace back. */ 
int solve(int n, int *last) { 
    int b, i; 
    int best = -1; 

    /* Need to blank the DP and predecessor matrices */ 
    for (b = 0; b < N; ++b) { 
     for (i = 0; i < NBITS; ++i) { 
      m[b][i] = -2; 
      p[b][i] = -2; 
     } 
    } 

    for (b = 0; b < n; ++b) { 
     int x = subsolve(b, (1 << n) - 1); 
     if (x > best) { 
      best = x; 
      *last = b; 
     } 
    } 

    return best; 
} 

मेरे पीसी पर, इस बढ़त वजन बेतरतीब ढंग से 7s बारे में में रेंज [0, 1000) चुना के साथ एक 20x20 पूरा ग्राफ को हल करती है और (उसमें से आधे पूर्ववर्ती पता लगाने के लिए है) 160MB के बारे में की जरूरत है।

+0

क्या आप इस एल्गोरिदम के साथ आए थे, या आपने इसे कहीं पढ़ा था? –

+1

@ क्रैग: मैं निश्चित हूं कि कुछ अन्य लोग इसके साथ पहले आए हैं, लेकिन हाँ मैं इसके साथ स्वयं आया हूं। मैंने फ़्लॉइड-वॉर्शल एल्गोरिदम के बारे में सोचकर शुरुआत की (जो ओ (एन^3) समय में प्रत्येक जोड़ी के बीच * सबसे छोटा * पथ पाता है) - मैंने शुरू में सोचा था कि आप बस सबसे लंबे समय तक * सबसे लंबे समय तक * पथ ढूंढ पाएंगे चिन्ह। लेकिन यह काम नहीं करता है क्योंकि एफ-डब्ल्यू द्वारा पाई गई पथ कुछ बार दो बार देख सकती है। बीटीडब्लू ने इसे थोड़ा गड़बड़ कर लिया: मेरी पहली कोशिश ने एक समारोह 'एम (ए, बी, यू)' का उपयोग किया जो यू के माध्यम से ए और बी के बीच सबसे लंबी दूरी दर्ज करता है। बाहर निकलता है हमें किसी के बारे में परवाह करने की आवश्यकता नहीं है। –

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