एक ग्राफ में सबसे लंबा चक्र


18

एक निर्देशित ग्राफ को देखते हुए, सबसे लंबे चक्र का उत्पादन।

नियम

  • किसी भी उचित इनपुट प्रारूप की अनुमति है (जैसे किनारों की सूची, कनेक्टिविटी मैट्रिक्स)।
  • लेबल महत्वपूर्ण नहीं हैं, इसलिए आप उन लेबलों पर कोई प्रतिबंध लगा सकते हैं जिनकी आपको आवश्यकता है और / या इच्छा है, इसलिए जब तक वे अतिरिक्त जानकारी इनपुट में नहीं दी जाती हैं (जैसे आपको आवश्यकता नहीं हो सकती है कि चक्र में नोड्स हैं) पूर्णांक के साथ लेबल, और अन्य नोड्स को अल्फाबेटिक स्ट्रिंग्स के साथ लेबल किया जाता है)।
  • एक चक्र नोड्स का एक अनुक्रम है जो सभी जुड़े हुए हैं, और कोई नोड दोहराया नहीं जाता है, नोड के अलावा अन्य चक्र की शुरुआत और अंत है ( [1, 2, 3, 1]यह एक चक्र है, लेकिन [1, 2, 3, 2, 1]नहीं है)।
  • यदि ग्राफ एसाइक्लिक है, तो सबसे लंबे चक्र की लंबाई 0 है, और इस तरह एक खाली आउटपुट (उदाहरण के लिए खाली सूची, सभी पर कोई आउटपुट नहीं) होना चाहिए।
  • चक्र में नोड्स की सूची के अंत में पहला नोड दोहराना वैकल्पिक है ( [1, 2, 3, 1]और [1, 2, 3]उसी चक्र को निरूपित करें)।
  • यदि एक ही लंबाई के कई चक्र हैं, तो उनमें से कोई एक या सभी आउटपुट हो सकते हैं।
  • बिल्डिंस की अनुमति है, लेकिन यदि आपका समाधान एक का उपयोग करता है, तो आपको एक वैकल्पिक समाधान शामिल करने के लिए प्रोत्साहित किया जाता है जो ट्रिवियलाइजिंग बिल्डिंस का उपयोग नहीं करता है (उदाहरण के लिए एक बिलिन जो सभी चक्रों को आउटपुट करता है)। हालाँकि, वैकल्पिक समाधान आपके स्कोर की ओर बिल्कुल भी नहीं गिना जाएगा, इसलिए यह पूरी तरह से वैकल्पिक है।

परीक्षण के मामलों

इन परीक्षण मामलों में, इनपुट को किनारों की एक सूची के रूप में दिया जाता है (जहां पहला तत्व स्रोत नोड है और दूसरा तत्व गंतव्य नोड है), और आउटपुट पहले / अंतिम नोड की पुनरावृत्ति के बिना नोड्स की एक सूची है।

[(0, 0), (0, 1)] -> [0]
[(0, 1), (1, 2)] -> []
[(0, 1), (1, 0)] -> [0, 1]
[(0, 1), (1, 2), (1, 3), (2, 4), (4, 5), (5, 1)] -> [1, 2, 4, 5]
[(0, 1), (0, 2), (1, 3), (2, 4), (3, 0), (4, 6), (6, 8), (8, 0)] -> [0, 2, 4, 6, 8]
[(0, 0), (0, 8), (0, 2), (0, 3), (0, 9), (1, 0), (1, 1), (1, 6), (1, 7), (1, 8), (1, 9), (2, 1), (2, 3), (2, 4), (2, 5), (3, 8), (3, 1), (3, 6), (3, 7), (4, 1), (4, 3), (4, 4), (4, 5), (4, 6), (4, 8), (5, 0), (5, 8), (5, 4), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (6, 7), (6, 9), (7, 0), (7, 1), (7, 2), (7, 3), (7, 4), (7, 5), (7, 8), (7, 9), (8, 0), (8, 1), (8, 2), (8, 5), (8, 9), (9, 1), (9, 2), (9, 3), (9, 4), (9, 5), (9, 6)] -> [0, 9, 6, 7, 8, 2, 5, 4, 3, 1]
[(0, 0), (0, 2), (0, 4), (0, 5), (0, 7), (0, 9), (0, 11), (1, 2), (1, 4), (1, 5), (1, 8), (1, 9), (1, 10), (2, 0), (2, 1), (2, 3), (2, 4), (2, 5), (2, 6), (3, 0), (3, 1), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (3, 11), (4, 1), (4, 3), (4, 7), (4, 8), (4, 9), (4, 10), (4, 11), (5, 0), (5, 4), (5, 6), (5, 7), (5, 8), (5, 11), (6, 0), (6, 8), (6, 10), (6, 3), (6, 9), (7, 8), (7, 9), (7, 2), (7, 4), (7, 5), (8, 8), (8, 9), (8, 2), (8, 4), (8, 7), (9, 0), (9, 1), (9, 2), (9, 3), (9, 6), (9, 10), (9, 11), (10, 8), (10, 3), (10, 5), (10, 6), (11, 2), (11, 4), (11, 5), (11, 9), (11, 10), (11, 11)] -> [0, 11, 10, 6, 9, 3, 8, 7, 5, 4, 1, 2]

आपके सभी उदाहरणों में, आपका आउटपुट सबसे छोटे सूचकांक के साथ नोड से शुरू होता है। क्या यह एक आवश्यकता है?
दादा

@ दादा नहीं, यह परीक्षण के मामलों के साथ सिर्फ एक संयोग है। चक्र में पहले नोड के साथ आउटपुट शुरू (और वैकल्पिक रूप से समाप्त) होना चाहिए।
मैगो

आपको एक प्रारूप चुनना चाहिए, समापन बिंदु के साथ या बिना मनमाना है और चुनौती के लिए कुछ भी नहीं जोड़ता है।
मैजिक ऑक्टोपस Urn

5
@carusocomputing मैं असहमत हूं। अंतिम नोड को निहित किया जाता है यदि छोड़ दिया जाता है (क्योंकि यह पहले नोड के समान है)। पहली नोड को दोहराने या न करने का विकल्प चुनने से गोल्फिंग में अधिक स्वतंत्रता मिलती है।
मीगो

जवाबों:


4

मैथेमेटिका, 80 58 बाइट्स

जंगवान मिन की बदौलत 22 बाइट्स बचाए

(FindCycle[#,∞,All]/.{}->{Cases[#,v_v_]})[[-1,;;,1]]&

तीन बाइट निजी उपयोग चरित्र का U+F3D5प्रतिनिधित्व करता है \[DirectedEdge]। पहले तर्क के साथ शुद्ध कार्य #निर्देशित किनारों की सूची होने की उम्मीद है। ढूंढता है Allअधिक से अधिक लंबाई के चक्र Infinityमें Graph@#, तो स्वयं छोरों की सूची के साथ खाली सूची बदल देता है। चक्रों को किनारों की सूची के रूप में दर्शाया जाता है और लंबाई के अनुसार क्रमबद्ध किया जाता है, इसलिए हम इस तरह के अंतिम चक्र को लेते हैं, फिर इसके सभी किनारों से हम पहला तर्क लेते हैं ताकि हम निर्दिष्ट आउटपुट प्रारूप में कोने की सूची प्राप्त करें।

यदि केवल गणितज्ञ ने छोरों को लंबाई के चक्र के रूप में माना है 1( गंभीरता से AcyclicGraphQ @ CycleGraph[1, DirectedEdges -> True]देता है True), तो हम एक और 26बाइट बचा सकते हैं :

FindCycle[#,∞,All][[-1,;;,1]]&

1
आपको इसकी आवश्यकता नहीं होगी MaximalByक्योंकि इसका परिणाम FindCycleपहले से ही लंबाई के अनुसार क्रमबद्ध होता है (अंतिम तत्व सबसे लंबा होता है)। इसके अलावा, का पहला तर्क (के बजाय ) की एक FindCycleसूची हो सकती है । इसके अलावा, आप 2-बाइट का उपयोग कर सकते (= 3-बाइट के बजाय) में एक बाइट बचाने के लिए। -22 बाइट्स (58 बाइट्स):\[DirectedEdge]Graph;;1;;-1AllPart(FindCycle[#,∞,All]/.{}->{Cases[#,v_v_]})[[-1,;;,1]]&
जुंगहवान मिन

3

हास्केल , 157 154 150 बाइट्स

import Data.List
g#l=nub[last$(e:d):[d|p==last q||e`elem`init d]|d@(p:q)<-l,[e,f]<-g,p==f]
h g=snd$maximum$((,)=<<length)<$>[]:until((==)=<<(g#))(g#)g

इसे ऑनलाइन आज़माएं!

धन्यवाद @Laikoni और @Zrabrab बाइट्स का एक गुच्छा बचाने के लिए!

यह एक बहुत ही अक्षम कार्यक्रम है:

पहला फ़ंक्शन #पथों की एक सूची लेता है l(संख्याओं की सूची) और प्रत्येक तत्व के lहर संभव किनारे (लंबाई 2 की एक सूची) को तैयार करके तत्वों के विस्तार की कोशिश करता gहै l। यह केवल तभी होता है जब तत्व lपहले से ही चक्र नहीं होता है और यदि नया नोड जो पहले से तैयार होता है वह पहले से ही तत्व में निहित नहीं है l। यदि यह पहले से ही एक चक्र है, तो हम कुछ भी पूर्व निर्धारित नहीं करते हैं, लेकिन इसे फिर से पथों की नई सूची में जोड़ते हैं, यदि हम इसे बढ़ा सकते हैं, हम विस्तारित पथ को नई सूची में जोड़ते हैं, अन्यथा हम इसे नई सूची में नहीं जोड़ते हैं ।

अब फ़ंक्शन hबार-बार उन रास्तों (किनारों की सूची के साथ शुरू) का विस्तार करने की कोशिश करता है जब तक कि हम एक निश्चित बिंदु तक नहीं पहुंच जाते हैं, अर्थात हम किसी भी मार्ग को आगे नहीं बढ़ा सकते हैं। इस बिंदु पर हमारी सूची में केवल चक्र हैं। फिर यह सबसे लंबे चक्र को चुनने की बात है। जाहिर है कि इस सूची में कई बार चक्र दिखाई देते हैं क्योंकि चक्र का हर संभव चक्रीय घूमना फिर से एक चक्र है।


आप कोष्ठक में छोड़ सकते हैं (p:q)<-l
लैकोनी

और <$>इसके बजाय का उपयोग करके mapएक और बाइट में बचाना चाहिए ((,)=<<length)<$>[]:
लकोनी

@Laikoni बहुत बहुत धन्यवाद!
दोष

अंतिम पंक्ति के बाद आपके पास एक अतिरिक्त जगह है। इसके अलावा, d@(p:q)<-lकुछ बाइट्स करने से बचाता है।
जर्बर्ब

ओह, d@(p:q)वास्तव में अच्छा है, मुझे दिखाने के लिए धन्यवाद!
दोष

2

अजगर, 20 बाइट्स

eMefqhMT.>{eMT1s.pMy

परीक्षण सूट

उदाहरणों की तरह, किनारों की एक सूची लेता है।

स्पष्टीकरण:

eMefqhMT.>{eMT1s.pMy
eMefqhMT.>{eMT1s.pMyQ    Variable introduction
                   yQ    Take all subsets of the input, ordered by length
                .pM      Reorder the subsets in all possible ways
               s         Flatten
                         (This should be a built in, I'm going to make it one.)
   f                     Filter on (This tests that we've found a cycle)
    qhMT                 The list of first elements of edges equals
           eMT           The last elements
         .>   1          Rotated right by 1
        {                Deduplicated (ensures no repeats, which would not be a
                         simple cycle)
  e                      Take the last element, which will be the longest one.
eM                       Take the last element of each edge, output.

2

बैश + bsdutils, 129 बाइट्स

sed 's/^\(.*\) \1$/x \1 \1 x/'|sort|(tsort -l>&-)|&tr c\\n '
 '|sed 's/x //g'|awk 'm<NF{m=NF;gsub(/[^0-9 ] ?/,"");print}'|tail -1

tsort सभी हैवी लिफ्टिंग करता है, लेकिन इसका आउटपुट फॉर्मेट अनोखा है और यह लंबाई 1 के चक्रों का पता नहीं लगाता है। ध्यान दें कि यह GNU tsort के साथ काम नहीं करता है।

सत्यापन

--- t1 ---
0
--- t2 ---
--- t3 ---
0 1
--- t4 ---
1 2 4 5
--- t5 ---
0 2 4 6 8
--- t6 ---
0 2 1 6 3 7 4 8 9 5
--- t7 ---
0 11 10 3 1 2 4 7 5 8 9 6

2

जावास्क्रिप्ट (ईएस 6), 173 163 156 145 139 बाइट्स

सहेजे गए 5 बाइट्स @Neil का धन्यवाद

f=(a,m,b=[])=>a.map(z=>!([x,y]=z,m&&x-m.slice(-1))&&b.length in(c=(n=m||[x],q=n.indexOf(y))?~q?b:f(a.filter(q=>q!=z),[...n,y]):n)?b=c:0)&&b

टेस्ट स्निपेट


निश्चित रूप से एक सादे पुराने पर स्विच करने mapसे आप बाइट के एक जोड़े को बचाता है?
नील

@ नील यह होना चाहिए .filter().map(), तो लगभग निश्चित रूप से नहीं। स्विच ने मुझे 10 बाइट्स बचाए (हालांकि यह अब पूरी तरह से गोल्फ की तरह नहीं था)
ETHproductions

मैं आपको समझ के परिणाम का उपयोग नहीं करता, इसलिए उपयोग करने के बजाय a.filter(z=>!e).map(z=>d)आप उपयोग कर सकते हैं a.map(z=>e?0:d)
नील

आप सही हैं, मैं 5 बाइट्स को बचाने के लिए सब कुछ गठबंधन कर सकता हूं। और मुझे एहसास हुआ कि मुझे जरूरत नहीं है a+a?:-)
ETHproductions

क्या डाउनवॉटर समझा सकता है कि क्या गलत है? क्या यह गलत आउटपुट देता है?
ETHproductions

2

हास्केल , 109 108 बाइट्स

import Data.List
f g=last$[]:[b|n<-[1..length g],e:c<-mapM(\_->g)[1..n],b<-[snd<$>e:c],b==nub(fst<$>c++[e])]

एक जानवर बल समाधान: बढ़ती लंबाई के किनारों की सभी सूचियां उत्पन्न करें जब तक कि इनपुट की लंबाई तक, उन चक्रों को रखें, जो पिछले एक को वापस करते हैं। प्रारूप में ग्राफ लेता है [(1,2),(2,3),(2,4),(4,1)]इसे ऑनलाइन आज़माएं!

व्याख्या

f g=                    -- Define function f on input g as
  last$                 -- the last element of the following list
  []:                   -- (or [], if the list is empty):
  [b|                   --  lists of vertices b where
   n<-[1..length g],    --  n is between 1 and length of input,
   e:c<-                --  list of edges with head e and tail c is drawn from
    mapM(\_->g)[1..n],  --  all possible ways of choosing n edges from g,
   b<-[snd<$>e:c],      --  b is the list of second elements in e:c,
   b==                  --  and b equals
    nub(fst<$>c++[e])]  --  the de-duplicated list of first elements
                        --  in the cyclic shift of e:c.

अब जब तक मुझे यह समझ में नहीं आया कि आखिर क्या हो रहा है, पथ / चक्रों की जाँच का हिस्सा वास्तव में चतुर है, मैं चकित हूँ!
दोष

@flawr धन्यवाद! ठीक है, ऐसा प्रतीत होता है कि इसहाक का उपयोग मेरे सामने अनिवार्य रूप से एक ही एल्गोरिदम के रूप में किया जाता है।
जर्गब

0

MATLAB, 291 260 बाइट्स

एक सहायक मैट्रिक्स लेता है Aजहां एक किनारे (i,j)को एक 1में चिह्नित किया जाता है A(i,j), और Aअन्य सभी प्रविष्टियों में शून्य होता है। आउटपुट एक सबसे लंबे चक्र की एक सूची है। यदि कोई चक्र बिल्कुल नहीं है तो सूची खाली है, और यदि चक्र है तो सूची में प्रारंभ और समापन बिंदु शामिल हैं। यह उपयोगकर्ता है1 आधारित इंडेक्सिंग ।

यह समाधान ग्राफ़ से संबंधित किसी भी अंतर्निहित फ़ंक्शन का उपयोग नहीं करता है।

function c=f(A);N=size(A,1);E=eye(N);c=[];for j=1:N;l=g(j);if numel(l)>numel(c);c=l;end;end;function p=g(p)if ~any(find(p(2:end)==p(1)))e=E(p(end),:)Q=find(e*A)k=[];for q=Q;if ~ismember(q,p(2:end))n=g([p,q]);if numel(n)>numel(k);k=n;end;end;end;p=k;end;end;end

दुर्भाग्य से यह TryItOnline में नहीं चलता है क्योंकि यह एक फ़ंक्शन के भीतर फ़ंक्शन का उपयोग करता है, जो पुनरावर्ती है। थोड़ा सा संशोधन आपको octave-online.net पर इसे आज़माने की अनुमति देता है ।

बहुत अंतिम परीक्षण के मामले में मुझे एक वैकल्पिक सबसे लंबा चक्र मिला [0 2 1 4 3 5 7 8 9 11 10 6 0](यह अंकन 0-आधारित अनुक्रमण का उपयोग करता है)

व्याख्या

यहां मूल दृष्टिकोण यह है कि हम प्रत्येक नोड से बीएफएस करते हैं और ध्यान रखते हैं कि हम स्टार्ट नोड को छोड़कर फिर से किसी भी मध्यवर्ती नोड पर न जाएं। उस विचार के साथ हम सभी संभव चक्रों को इकट्ठा कर सकते हैं, और आसानी से सबसे लंबे समय तक उठा सकते हैं।

function c=f(A);
N=size(A,1);
E=eye(N);
c=[]; % current longest cycle
for j=1:N;                                      % iterate over all nodes
    l=getLongestCycle(j);                       % search the longest cycle through the current node
    if numel(l)>numel(c);                       % if we find a longer cycle, update our current longest cycle
        c=l;
    end;

end;

    function p=getLongestCycle(p);              % get longest cycle from p(1) using recursion
        if ~any(find(p(2:end)==p(1)));          % if we just found a cycle, return the cycle do nothing else, OTHERWISE:
            e=E(p(end),:);                      % from the last node, compute all outgoing edges
            Q=find(e*A);                        
            k=[];                               
            for q=Q;                            % iterate over all outogoin edges
                if ~ismember(q,p(2:end));       % if we haven't already visited this edge,
                    n=getLongestCycle([p,q]);   % recursively search from the end node of this edge
                    if numel(n)>numel(k);       % if this results in a longer cycle, update our current longest cycle
                        k=n;
                    end;
                end;
            end;
            p=k;
        end;
    end; 
end
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.